クライアントが C++ で Winsock を介して切断されたかどうかを確認するにはどうすればよいですか?
4 に答える
ブロッキングモードでrecvを呼び出し、0バイトの読み取りで戻った場合、ソケットは切断されています。それ以外の場合は、バイトが受信されるのを待ちます。
このページのselectからの例。
int nRet;
if(( nRet = select( 0, &fdread, NULL, NULL, NULL )) == SOCKET_ERROR )
{
// Error condition
// Check WSAGetLastError
}
if( nRet > 0 )
{
// select() will return value 1 because i m using only one socket
// At this point, it should be checked whether the
// socket is part of a set.
if( FD_ISSET( s, &fdread ))
{
// A read event has occurred on socket s
}
}
データの送信を試みることによってのみ、TCPソケットが「切断」されているかどうかを判断できます。これは、プロトコルの設計が、ピア間の一時的な停止を考慮に入れているためです。したがって、AからR1を介してR2を介してR3を介してBに接続し、しばらくの間データを送信してから送信を停止すると、R2-> R3のプラグを抜くことができ(たとえば)、AもBも気付かない(または気にしない)。次に、R2->R4とR4->R3を接続し、AとBの間でデータを送信しようとすると、状況は「正常に機能」し、わかりません。ただし、R2-> R3が切断されたときにデータを送信しようとすると、(最終的には、すべてのTCPレベルの再試行後に)エラーが返されます。
現在、一部のオペレーティングシステムでは、ローカルネットワークアダプターが現在接続されていないという事実を警告できる場合があります。これを使用して、「ピアに接続されていません」と言うことができますが、アドバイスはしません。
接続が「切断」されたことをピアに知らせることが重要な場合は、アプリケーションレベルの「ping」メッセージを使用してピア間でデータを送信するか、TCPキープアライブを使用します。個人的にはpingメッセージを送信します...
編集:もちろん、接続でデータを送信できるかどうかを知りたいと仮定しているのは、結局のところ、読み取りが0バイトを返し、切断するとわかるため、クライアントが送信しなくなったときにTOLDになります書き込みが失敗するため、送信側。また、接続の自分の端の送信側または受信側のいずれかをシャットダウンするときも知っています...
私は「切断されたと定義する」という最初の腸反応反応に固執するべきだったと思います;)
いくつかの異なる方法がありますが、最も一般的なのは、送信または受信コマンドの結果を確認することです。
nReadBytes = recv(sd, ReadBuffer, BufferSize, 0);
if (nReadBytes == SOCKET_ERROR)
{
//error
}
nSendBytes = send(sd, WriteBuffer, BufferSize, 0);
if (nSendBytes == SOCKET_ERROR)
{
//error
}
その他の例(クライアントとサーバーの両方でエラーチェックを完了):