単純なwinsockクライアント/サーバーアプリケーションがあります。ほとんどすべてが正常に機能しますが、クライアントアプリケーションが終了してもrecvが値を返さない場合があります。
MSDNからの引用:
エラーが発生しない場合、recvは受信したバイト数を返し、bufパラメーターが指すバッファーには受信したこのデータが含まれます。接続が正常に閉じられている場合、戻り値はゼロです。それ以外の場合は、SOCKET_ERRORの値が返され、WSAGetLastErrorを呼び出すことで特定のエラーコードを取得できます。
そのrecvがクライアントに接続せずに二度と戻らず、永久にハングする理由は何でしょうか?
関連するサーバーコード:
const
BUFSIZE = 512;
var
Sock: TSocket;
I : Integer;
Buf : AnsiString;
begin
repeat
SetLength(Buf, BUFSIZE);
//blocking call
I := recv(Sock, Pointer(Buf)^, BUFSIZE, 0);
if I > 0 then
begin
SetLength(Buf, I);
//do s.th. with Buf
end;
until I <= 0; //Connection closed or error
//Sometimes never here
Synchronize(procedure
begin
FOnConnectionClosed(Self, Sock, WSAGetLastError);
end);
end.