2012-04-17 2 views
0

비 차단 소켓의 경우 원격 클라이언트가 정상적으로 연결이 끊어지면 recv()이 오류 코드없이 0을 반환한다는 것을 알고 있습니다 (우리가 서버라고 가정). 비정상적인 단절은 어떻게 감지합니까? recv()은 여전히 ​​0을 반환합니까, 아니면이를 감지하기 위해 API를 사용하는 다른 방법이 있습니까?winsock2의 비정상적인 연결 끊김을 감지하는 방법은 무엇입니까?

+0

recv()에 대한 MSDN을 살펴보십시오. 모든 것이 드러날 것입니다! –

답변

2

소켓이 정상적으로 닫히지 않고 연결이 물리적으로 끊어 지거나 다른 호스트가 종료 된 경우 recv이 영원히 대기합니다. 소켓 수준에서 select()을 사용하고 대기중인 데이터가 소켓에서 읽을 수 있도록 시간 제한을 설정할 수 있습니다. 당신은 이것을 반복 할 것이며 만약 데이터가 이용 가능하다면 - 그것을 읽으십시오 (recv()); select() 시간이 초과되면 소켓을 정상적으로 닫은 다음 다시 연결하십시오.

또 다른 솔루션은 프로토콜에 연결 유지를 구현 한 것입니다. 한 쪽에서는 주기적으로 메시지를 보내고 다른 쪽에서는 시간 초과가 설정된 타이머 (송신 기간에 맞게 조정 됨)가 있고 기다리고 있습니다. 타이머 시간이 초과되면 "대기중인"호스트는 소켓을 닫고 다시 연결을 시도합니다.

+0

좋은 지적 - OP가 '비정상적인 연결 끊김'으로 의미하는 것이면 오랫동안 기다릴 수 있습니다. –

-2

recv()에 대한 MSDN에서 특히 무엇을 반환하는지보십시오. 모든 것이 드러날 것입니다!

+0

'비정상적인 연결 해제'<> 연결이 끊어지지 않았 음을 참고하십시오! 네트워크 케이블이 피어에서 빠져 나와 데이터를 보내지 않으려 고하면 (즉, 데이터를 기다리는 중입니다.) @Bojan에 의해 지적 된대로 영원히 기다릴 수 있습니다 –

+0

제 질문을 자세히 검토하십시오. 비정상적인 연결 해제 (또는 비정상적인 연결 해제)에 대해 질문했습니다. recv() 문서는 _graceful_ 연결 해제 중 0을 반환합니다. –

+0

'going away'서버는 클라이언트 POV와의 비정상적인 연결 해제가 아닙니다. WSAECONNRESET, WSAETIMEDOUT 또는 WSAECONNABORTED는 WSAGetLastError()가 반환 한 비정상적인 연결 해제입니다. recv()는 SOCKET_ERROR와 함께 반환됩니다. 반 연결이 비정상적으로 끊어지지는 않습니다. –

관련 문제