2009-08-25 3 views
8

tcp 서버와 클라이언트가 연결된 경우 클라이언트가 더 이상 연결되어 있지 않은지 확인하고 싶습니다. 클라이언트에 메시지를 보내려고하면이 작업을 간단히 수행 할 수 있다고 생각하고 -1을 반환하면 send()가 소켓을 끊어 버릴 수 있습니다. 이 구현은 Windows에서 작동하지만 BSD 소켓을 사용하여 Linux에서이 작업을 시도하는 순간 클라이언트가 더 이상 연결되어 있지 않으면 서버 측 응용 프로그램에서 send()를 호출하면 내 서버 응용 프로그램이 중단됩니다. -1을 반환하지 않습니다 ... 그냥 프로그램을 종료합니다.TCP 보내기가 원인 크래킹 프로세스를 반환하지 않습니다.

왜 이런 일이 발생하는지 설명하십시오. 미리 감사드립니다!

답변

13

이것은 SIGPIPE 신호 때문에 발생합니다. 경우

센드() 함수는 실패한다 : send(2) 참조
이 [EPIPE] 소켓이 쓰기에 종료, 또는 소켓이 연결 모드 더 이상 연결되어 있습니다. 후자의 경우 소켓이 SOCK_STREAM 또는 SOCK_SEQPACKET 유형이고 MSG_NOSIGNAL 플래그가 설정되어 있지 않으면 SIGPIPE 신호가 호출 스레드로 생성됩니다.

당신은, 또는 프로그램의 시작 부분에 signal(SIGPIPE, SIG_IGN)SIGPIPE 신호를 무시하여 send() 전화에 MSG_NOSIGNAL 플래그를 사용하여이 문제를 피할 수 있습니다. 이 경우 send() 함수는 -1을 반환하고 errnoEPIPE으로 설정합니다.

2

SIGPIPE 신호를 무시해야합니다. 소켓에서 쓰기 오류가 발생하면 프로세스가 SIGPIPE을 얻고 그 신호의 기본 동작은 프로세스를 종료하는 것입니다. * nix에 일반적으로 원하는 네트워킹 코드 작성 :

signal(SIGPIPE,SIG_IGN); 
관련 문제