タイトルで述べたように、キープアライブ オプションを使用して、サーバー側で停止したクライアントを検出しています。接続された tcp ソケットでキープアライブを有効にするコード スニペットは、次のようになります。TCP_KEEPCNT、TCP_KEEPIDLE、TCP_KEEPINTVL などのキープアライブ動作を操作するその他のオプションは、デフォルトでシステムです。
int optval;
socklen_t optlen = sizeof(optval);
if(setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
perror("setsockopt()");
close(s);
exit(EXIT_FAILURE);
}
サーバー側では、接続されたソケットで、サーバー スレッドが recv 呼び出しになり、クライアントがサーバーにコマンドを送信するのを待ちます。このコード スニペットは次のようになります。
for(; dwBytesReceived < dwBlockSize; dwBytesReceived += iByteCount) {
retry:
iByteCount = recv(m_ConnectSocket, ((UX_CHAR *)pBlock + dwBytesReceived), (dwBlockSize - dwBytesReceived), flag);
if (UX_SUCCESS >= iByteCount) {
if (iByteCount == 0) {
// Connection from client is unexpectedly closed. Terminate Server instance thread.
ret = UX_ECLIENTSHUTDOWN;
UX_ERROR("Connection from client is unexpectedly closed. Terminating Server instance thread, errno:%d", UX_ECLIENTSHUTDOWN);
goto out;
}
ret = get_last_sock_error();
if (EAGAIN == ret) {
UX_ERROR("The socket is marked non-blocking and the requested operation, recv, would block");
goto retry;
}
ret = -errno;
goto out;
}
}
クライアントが正常にシャットダウンすると、recv 呼び出しは 0 を返し、クライアントが終了したことを確認します。だから私の質問は、キープアライブがデッドクライアントを検出したときにrecvが返すものは何ですか? または、「get_last_sock_error」から読み取ることができるシステムエラー変数にエラーを設定し、クライアントが停止していることを確認します。ありがとう。