0

C++ TCP クライアント プログラムをアップグレードして Windows 7 と互換性を持たせようとしています。プログラムはノンブロッキング ソケットを使用するように設定されており、Windows XP で問題なく動作します。しかし、Windows 7 で同じコードを実行したところ、ソケット クラスの recv 関数の動作が異なることがわかりました。

PC からイーサネット ケーブルを切断しようとすると、Windows XP と Windows 7 の両方がシステム トレイでネットワークが切断されていることを検出します。でも、

Windows XP では、recv は SOCKET_ERROR を返し、WSAGetLastError は WSAECONNRESET を返します。

Windows 7 では、recv は SOCKET_ERROR を返しますが、WSAGetLastError は WSAEWOULDBLOCK を返します。

ソケット recv 関数が、ソケットがまだ接続されていると見なし (つまり、WSAEWOULDBLOCK を返す)、キープアライブ タイムアウト後に切断があることのみを検出する理由に興味があります。

また、recv 関数を呼び出した後に WSAGetLastError の値を確認する以外に、TCP ソケット ライブラリを使用してネットワークが切断されたことを検出する別の方法はありますか?

どうもありがとう!

4

2 に答える 2

0

ループselectを使用してデータを待機している可能性があります。その場合、疑似コードのアイデアは次のとおりです。

bool ping_outstanding = false;
while (running) {
   waitForDataMaxSeconds(5);
   if (dataAvailable()) {
      // all is good
      ping_outstanding = false;
      getData(); // Could be normal data or a ping response
   }
   else if ( !ping_outstanding ) {
      ping_outstanding = true;
      sendPing();
      // I should get data in response to this
   }
   else {
      // I've got connection trouble!
   }
}

もちろん、システム要件に基づいて、ping 要求を送信するまでの待機時間を調整したり、応答を期待する時間を調整したりできます。

他の「データ待ち」表示を使用している場合は、ループの代わりに非同期タイマーを使用できますが、考え方は同じです...データを受信しない場合は、データを要求するものを送信してください。それでもデータを受信しない場合は、問題があると考えてください。

于 2013-10-23T13:34:35.110 に答える