0

iocp メカニズムに基づいてネットワーク通信を管理するための複雑なライブラリを作成しました。問題は、サーバーが API メソッド closesocket() を呼び出して接続を閉じると、この情報が数秒または数分遅れてクライアントに送信されることがあるということです。接続閉鎖を検出するための私のコードは次のようになります (簡略化):

ok = GetQueuedCompletionStatus(completion_port, &io_size, (PULONG_PTR)&context, &overlapped, 40);

if (!ok) {
   // something went broken
  DWORD err = GetLastError();
  if (err == ERROR_CONNECTION_REFUSED) {
         // connection failed
  } else if (err == ERROR_SEM_TIMEOUT) {
        // connection timeout
  } else if (err == ERROR_NETNAME_DELETED) {
        // connection closure - point of interest
  } else if (err != WAIT_TIMEOUT) {
        // unknown error
  }
} else {
    // process incomming or outgoing data
}

なぜこうなった?バックアップサーバーに接続できるようにするには、接続の閉鎖についてすぐに知る必要があります(負荷がそれほど高くないため、切断が発生しています)。

4

2 に答える 2

1

どのように接続を閉じていますか?

呼び出しているだけの場合closesocket()は、現在保留中のすべてのデータが宛先に確実に到達するように試行するシャットダウン シーケンスを開始しています。特に、ネットワーク接続が過負荷になり、データグラムが失われ、TCP の再送信が発生している場合は、時間がかかることがあります。

接続をすぐに閉じて、保留中のデータをすべて失いたい場合は、linger を 0 に設定してからソケットを閉じます。これにより、接続で RS​​T が発行され、はるかに高速になります。

于 2011-04-29T20:40:12.233 に答える
0

Len が書いたように linger パラメータを試してみましたが、これは役に立ちませんでした。closesocket() の直前に shutdown() 関数の呼び出しを追加すると助かりました。クライアントのネットワーク インターフェイスに到達するパケットを分析した後 (WireShark を使用)、RST パケットが FIN パケットに置き換えられていることがわかりました。興味深いことに、その RST パケットは遅延していませんでした。そのため、オペレーティング システムは接続が閉じられたことを認識していましたが、なんらかの不明な理由により、この情報がアプリケーション層に転送されるのが非常に遅れました。10 秒から 4 分の遅延を測定しました。

于 2011-05-01T10:07:56.530 に答える