2014-06-07 2 views
0

이것은 숙제 문제가 아닙니다.C - 정리하고 종료 할 다른 스레드에 알리기

난 내가 작성한 클라이언트/서버 쌍을

C.

을 배울 수있는 방법으로 시계열 데이터베이스 구현을 쓰고 있어요. 서버는 현재 포트의 소켓을 수신하는 반향 서버입니다. 클라이언트는 해당 포트에 연결하고 입력 라인을 포트에 보냅니다. 입력을 얻으려면 readline을 사용하고, 클라이언트 소켓에는 send을, 클라이언트 소켓에는 recv 줄을 입력하고 터미널에 줄을 인쇄합니다. 린스, 반복하십시오. 클라이언트는 을 recv에서 가져 오면 연결이 닫힌 것을 알 수 있습니다.

readline이 차단되어 서버 프로세스가 죽으면 (예 : I SIGINT) 클라이언트가 여전히 readline에서 차단 중입니다. send s 이후에 recvEOF이 될 때까지 서버가 사라 졌음을 알 수 있습니다. recv 즉시 종료에 EOF이 있다면 클라이언트가 신호를받을 때까지 나는이 발생 할 무엇

이다. 터미널에 대한 네트워크 클라이언트 (sendrecv) 1 - 2 내가 할 필요가 생각 무엇

3 pthreads를 만드는 것입니다. 터미널은 readline 및 블록을 호출합니다. 입력을 받아들이고 pthread_cond_t을 사용하여 대기 네트워크 클라이언트 send 스레드로 보낼 것을 알립니다. 네트워크 클라이언트 recv 스레드는 항상 recv입니다. 이는 차단됩니다. EOF 인 경우 SIGINT, 처리기가 pthread_kill이고 모든 스레드가 fprintf 인 경우 "Connection closed by server."와 같은 호출을 수행하고 exit을 호출합니다 (예 : exit은 모든 스레드를 종료합니다. 청결하고 내가 C를 이해하는지보기 위해서).

이 방법이 적절합니까? 분명히 네트워크 클라이언트 터미널은 항상이 작업을 수행합니다. 올바른 접근 방식은 무엇입니까?

+2

올바른 방법은 없습니다. 고전적인 참고 자료는 Rich Stevens의 [_UNIX Network Programming_]입니다. (http://www.amazon.com/Unix-Network-Programming-Volume-Networking/dp/0131411551) – arayq2

+0

@ arayq2 감사합니다! 나는 그것을 조사 할 것이다! – alyssackwan

+0

"* 입력을 얻기 위해 readline을 사용합니다 ... *" "* it *"은 클라이언트 또는 서버입니까? – alk

답변

1

이 질문은 전에 답변되었습니다. 스티븐스 (Stevens)와 5 장은 readline 호를 read 소켓으로 호출하여 EOF을 찾도록 제안했습니다.나는 libreadlineselect/poll에 대한 Google 검색을했고,이 보았다

Interrupting c/c++ readline with signals

가 인터리브를 사용하는 방법 거기를 I/O 그렇게 libreadline하지 않습니다 단지 블록 :

http://www.delorie.com/gnu/docs/readline/rlman_41.html

감사합니다 @ arayq2 및 @ G-- 스티븐스 제안!

1

readline 중에 올바르게 종료하고 싶다면 write()/send() 전에 서버가 종료 될 때 종료하십시오. 귀하의 접근 방식은 좋습니다. 서버가 사망 한 경우에 만날 수있는 유일한 방법은 write()/send()입니다. SIGPIPE을 입력하면 바로 종료됩니다. 기본적으로 전송하거나 승인 할 데이터가 없으면 연결에서 패킷이 전송되지 않기 때문입니다. 따라서 피어로부터 단순히 데이터를 기다리는 경우 피어가 자동으로 사라 졌는지 또는 더 이상 데이터를 아직 보내고받을 준비가되지 않았는지 알 수있는 방법이 없습니다. 그러므로 별도의 스레드에서 SIGPIPE에 대한 폴러가 필요하고 종료하면 종료하십시오. 이 readline 함수를 사용하여 검사를 시작할 수 있습니다.

/** 
* Simple utility function that reads a line from a file descriptor fd, 
* up to maxlen bytes -- ripped from Unix Network Programming, Stevens. 
*/ 
int 
readline(int fd, char *buf, int maxlen) 
{ 
    int n, rc; 
    char c; 

    for (n = 1; n < maxlen; n++) { 
    if ((rc = read(fd, &c, 1)) == 1) { 
     *buf++ = c; 
     if (c == '\n') 
     break; 
    } else if (rc == 0) { 
     if (n == 1) 
     return 0; // EOF, no data read 
     else 
     break; // EOF, read some data 
    } else 
     return -1; // error 
    } 

    *buf = '\0'; // null-terminate 
    return n; 
} 
+0

그건 의미가 있습니다. FWIW, 한 동료는 각 호출에 대해'read' 호출은 매우 비효율적이라고 말했습니다. 왜냐하면 각 호출은 커널에 의해 트랩되어야하기 때문입니다. 그게 사실인지, 그렇다면 어떤 영향을 미치는지 나는 모른다. 어쨌든, 실제로'libreadline'을 사용하여 ctrl 문자 기능을 내장하고 있습니다. 스티븐스를 조사 할께. – alyssackwan

관련 문제