重複の可能性:
シャットダウン後に Winsock recv が機能しない
WinSock2 経由で HTTP リクエストを送信しようとしています。ようやくやったのですが、接続の半分の送信をシャットダウンしたときに接続が閉じられる理由がわかりません。
RFC2616 sec8.1.4によると:
クライアントまたはサーバーがタイムアウトしたい場合は、トランスポート接続で適切なクローズを発行する必要があります。クライアントとサーバーは、トランスポートの反対側が閉じるのを常に監視し、必要に応じて応答する必要があります (SHOULD)。
ネットワークまたはクライアントの障害が疑われる場合を除き、サーバーは応答の送信中に接続を閉じるべきではありません。
サーバーが送信するものがなくなるまで、ソケットは引き続きメッセージを受信すると思いますが、サーバーは予期せず接続を閉じるだけです。
C:\Users\970067a\Desktop>gcc test.c -lWs2_32 && a
Bytes Sent: 59
Bytes received: 787
Bytes received: 222
Connection closed
C:\Users\970067a\Desktop>gcc test.c -lWs2_32 -D SHUTDOWN_SD_SEND && a
Bytes Sent: 59
Connection closed
以下は私のソースコードの一部です:
...
iResult = getaddrinfo("www.google.com", "http", &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return 1;
}
...
int recvbuflen = DEFAULT_BUFLEN;
char *sendbuf = "GET / HTTP/1.1\r\nhost: www.google.com\r\nConnection: close\r\n\r\n";
char recvbuf[DEFAULT_BUFLEN];
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection for sending since no more data will be sent
// the client can still use the ConnectSocket for receiving data
#ifdef SHUTDOWN_SD_SEND
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
#endif
// Receive data until the server closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
printf("Bytes received: %d\n", iResult);
else if (iResult == 0)
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while (iResult > 0);
// cleanup
closesocket(ConnectSocket);
WSACleanup();
...