SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

Socket.ReceiveTimeoutがWindows8で正確になった

Windows7までうまく動作していたソケット通信のプログラムが、Windwos8でタイムアウト多発のトラブルを発生させました。
デバッグの結果、タイムアウト値が不適切(短すぎる)という、障害状況からすると、ほんと当たり前の結果となり、タイムアウト値を増やすことで問題に対処しました。

しかし、今まで動作していたのはどういうことなんだ・・・・ということで、ちょっと試験してたところ私的にはビックリする結果となってしまいました。

テストプログラム

テスト用のプログラムは、下記のような感じです。
ReceiveTimeout(タイムアウト値)を変えながら、実際にタイムアウトする時間を計測しています。

private static void Main(string[] args) {
  var buf = new Byte[1];
  var ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 999);
  var socket = new Socket(ep.Address.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
  socket.Bind(ep);
  for (var msec = 1; msec < 100; ){
    Test(socket, buf, msec);
    msec = (msec < 10) ? (msec + 1) : (msec + 10);
  }
  socket.Close();
}
static void Test(Socket socket, byte[] buf, int msec) {
  socket.ReceiveTimeout = msec;
  var rp = (EndPoint)new IPEndPoint(IPAddress.Any, 0);
  var sw = new Stopwatch();
  try {
    sw.Start();
    socket.ReceiveFrom(buf, 0, buf.Length, SocketFlags.None, ref rp);
  } catch (Exception ex) {
    sw.Stop();
  } finally {
    sw.Stop();
  }
   Console.WriteLine(string.Format("ReceiveTimeout={0} break={1}ms", msec, sw.ElapsedMilliseconds));
}

Windows8の実行結果

Windows8の場合、指定した通りの数値でタイムしています。


c:\tmp2>ConsoleApplication2
ReceiveTimeout=1 break=1ms
ReceiveTimeout=2 break=2ms
ReceiveTimeout=3 break=3ms
ReceiveTimeout=4 break=3ms
ReceiveTimeout=5 break=4ms
ReceiveTimeout=6 break=5ms
ReceiveTimeout=7 break=6ms
ReceiveTimeout=8 break=7ms
ReceiveTimeout=9 break=8ms
ReceiveTimeout=10 break=9ms
ReceiveTimeout=20 break=20ms
ReceiveTimeout=30 break=30ms
ReceiveTimeout=40 break=40ms
ReceiveTimeout=50 break=49ms
ReceiveTimeout=60 break=60ms
ReceiveTimeout=70 break=69ms
ReceiveTimeout=80 break=80ms
ReceiveTimeout=90 break=90ms


Windows7の実行結果

Windows7の場合、+500msぐらいでタイム?


c:\tmp2>ConsoleApplication2
ReceiveTimeout=1 break=502ms
ReceiveTimeout=2 break=502ms
ReceiveTimeout=3 break=502ms
ReceiveTimeout=4 break=503ms
ReceiveTimeout=5 break=504ms
ReceiveTimeout=6 break=505ms
ReceiveTimeout=7 break=506ms
ReceiveTimeout=8 break=507ms
ReceiveTimeout=9 break=508ms
ReceiveTimeout=10 break=509ms
ReceiveTimeout=20 break=519ms
ReceiveTimeout=30 break=529ms
ReceiveTimeout=40 break=539ms
ReceiveTimeout=50 break=549ms
ReceiveTimeout=60 break=559ms
ReceiveTimeout=70 break=569ms
ReceiveTimeout=80 break=579ms
ReceiveTimeout=90 break=589ms

正確に動作するようになったってこと・・・・・? orz

これは、常識だったのでしょうか・・・また、私の実装方法に問題がるのか・・・・
ぜひ、教えてやってください。
 
結果的に・・・BlackJumboDogは、Ver5.7.5になりました。
http://blackjumbodog.codeplex.com/releases/view/103144