2014-11-20 3 views
2

RFC 7230는 HTTP/1.1 프로토콜을 정의하고 6.6에서 흥미로운 구절이있다, "연결 관리 눈물 다운."클라이언트가 내가 보낸 모든 데이터를 ACK 했습니까?

는 TCP 리셋 문제를 방지하려면, 서버는 일반적으로 단계에서 연결 을 닫습니다. 먼저, 서버는 읽기/쓰기 연결의 쓰기 측 만 닫음으로써 반 닫기를 수행합니다. 그런 다음 서버는 클라이언트에서 에 해당하는 닫기를 수신 할 때까지 또는 서버 자체의 TCP 스택이 클라이언트의 패킷 수신 확인을 수신했다고 합리적으로 확신 할 때까지 연결에서 읽은 을 계속 서버의 마지막에 포함 된 응답. 마지막으로 서버는 완전히 으로 연결을 닫습니다.

은 기본적으로 다음과 같은 귀결 : 정상 종료를 수행하는 표준 방법입니다

shutdown(s, SD_SEND); 
while (recv(s, throaway_buffer, throaway_buffer_len, 0) > 0); 
closesocket(s); 

합니다. 그러나 오작동하는 클라이언트가 존재할 수도 있으며 (클라이언트가 Connection: close 헤더로 응답을받은 후에도 요청을 계속 전송함) 클라이언트가 마지막 응답을받은 후 서버가 연결을 재설정하여이를 처리해야한다는 점도 인정합니다.

그러나 소켓 인터페이스는 send에 전달 된 모든 데이터가 원격 호스트에 의해 실제로 전송되고 ACK되었는지 여부를 알 수있는 기능을 제공하지 않는 것 같습니다. 실제로 거기에 있습니까? 그것 없이는, 내가 생각할 수있는 것은 타이머의 종류를 설정하고 원격 호스트가 연결을 닫았거나 시간이 초과 될 때까지의 어느 것이 든 먼저 도달 할 때까지 recv으로 전화하는 것입니다. 그러나 적절한 타임 아웃은 무엇입니까? 60 초 괜찮습니까?

답변

0

소켓 인터페이스는 거의 사용되지 않고 덜 이해되는 SO_LINGER 옵션을 통해이 평균을 제공합니다. 중에서은 대기 중 데이터가 전송되는 동안 close() 및 가능하면 shutdown()이 차단되는 시간 초과를 정의 할 수 있습니다. 그것은 거의 실용적이지 않으며 제가 언급 한 것처럼 거의 사용되지 않습니다 ... 적어도 거의 제대로 사용되지는 않습니다.

관련 문제