2009-05-12 3 views
7

標準のソケット呼び出しを使用するC++アプリケーションがあり、データを送受信しないでソケットがまだ開いているかどうかを知ることができますか?信頼できるselectまたはioctlsocketコールがありますか?ソケットがまだ開いていることを確認する方法はありますか?

+0

ソケットがもう一方の端で閉じられているかどうかを確認していますか? –

+0

はい。私のアプリケーションはWindows上で動作し、PCが休止状態になっているときに、ソケットが返ってきたらもう片方がそれを閉じて(そして私のアプリケーションが中断されているので、私は通知を受け取らないので)ソケットはもはや有効ではないかもしれません。 – Rob

答えて

7

1バイトを受信しようとすると、いくつかのエラーを受信することができます。ノンブロッキングソケットを使用し、有効な接続で受信しようとすると、WSAEWOULDBLOCKエラーが発生します。

あなたはタイムアウトまたは切断のためのいくつかの他のエラーを返すことがありreturn value of recvのrecvから見ることができるように、私はWSAEWOULDBLOCKが、それはかもしれない唯一の値である信じて、我々はそう

bool connected(SOCKET sock) 
{ 
    char buf; 
    int err = recv(sock, &buf, 1, MSG_PEEK); 
    if(err == SOCKET_ERROR) 
    { 
      if(WSAGetLastError() != WSAEWOULDBLOCK) 
      {return false;} 
    } 
    return true; 
} 

のような非ブロッキングソケットを確認することができ、これを知りますエラーがあっても接続されていればリターンしますが、戻り値のリストを再度チェックしたいかもしれません。また、recv(MSG_PEEK)で使用されているフラグは、チェックの後に表示するときにデータが読み込み可能であることを意味します。したがって、1バイトのデータを失うことを心配する必要はありません。

これはデータを受信するまでブロックされる可能性があるため、非ブロッキングソケットでのみうまくいくと思います。ブロッキングソケットを使用する場合は、このチェックの前にioctlsocketで非ブロックを設定し、それを元の状態に戻すことができます。

+0

ソケットをブロックするには、selectを使用します。 –

3

ソケットが「開いている」とは、エンドツーエンドの接続には役立ちません。あなたが相手と通信できることを確かめるための唯一の方法は、相手の側と通信することです。

設計するプロトコルでこのチェック動作を実装することを検討する必要があります。それがあなたのプロトコルではない場合、時にはそれを巧妙に行う方法があります(例えば、FTPポートが両方とも開いているかどうかを確認するために、非常に小さくて無駄なファイルをFTPします)。

関連する問題