お世話になっております。
.NET Framework 4.5.2 を使用してTCP通信クライアントアプリケーションを作成しています。
###質問
System.Net.Sockets.Socket.Poll メソッドの挙動について質問があります。
このメソッドは winsock.dll の select関数のような挙動をし、第一引数には「待機時間」を指定する(負の値の場合は無制限に待機)よう MSDNライブラリのヘルプに記載されているよう解釈しています。受信(または接続終了)待ちに利用してみているのですが、「待機時間」の値を負の値(永久待ち)にすると常にtrueが返され受信できる環境において「待機時間」に正の数を指定すると、受信状態がどうであれまったく(1秒ですら)待機しません。
このメソッドの「待機時間」とは、一体何なのでしょうか?
###コード
次のようなコードを記述してみています。
MyProgram.Start メソッドから起動させ、TCP 接続後 Poll メソッドで100秒のタイムアウトを指定して受信または接続終了の待機をさせるつもりです。サーバ側は、Accept後すぐに数十バイトのパケットを送信して受信待ちとなるものです。
下記コードの Poll メソッドから true が返され whileループ内のReceived メソッドで受信できる場合が多いのですが、たまにPollメソッドが(100秒どころか1秒もせずに)falseですぐに復帰してしまう場合があります。そのとき、val2 には 0ではない値(受信したであろうパケットの長さ)が入っていたりいなかったりし、0 でない場合はReceiveメソッドで受信できます。
ちなみにPollメソッドの第一引数を負の値にすると、Pollメソッドでは(サーバを止めたりしていなければ)常にtrueですぐに復帰し、Receiveパケットを受信できます。
C#
1public class CustomSocket :System.Net.Sockets.Socket 2{ 3 public CustomSocket () : base(System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.IP) { } 4 5 public void ReceiveAny() 6 { 7 while (base.Poll(100000, System.Net.Sockets.SelectMode.SelectRead)) // <- ここのPollメソッド 8 { 9 var val1 = base.Available; 10 if (val1 == 0) 11 break; // <- ここにブレイクポイントを置いてもヒットしないサーバ側の挙動(サーバ側から接続終了しない)で動かしてみています。netstat コマンドでも ESTABLISHED のままです。 12 var pkt = new byte[val1]; 13 base.Receive(pkt); 14 15 // (略) 16 } 17 System.Threading.Thread.Sleep(200); // <- ここで少し待機させてみる(300ms以上ではほぼ受信され、100ms以下ではうしろのbase.Availableは0となることが多いです) 18 var val2 = base.Available; 19 if(val2 > 0) { 20 var pkt2 = new byte[val2]; 21 base.Receive(pkt2); 22 } 23 // (略) 24 } 25} 26 27public static class MyProgram 28{ 29 public static void Start() 30 { 31 // address, port などをここで指定 32 var epRemote = new System.Net.IPEndPoint(address, port); 33 using(var soc = new CustomSocket ()) 34 { 35 soc.Connect(epRemote); 36 soc.ReceiveAny(); 37 // (略) 38 } 39 } 40}
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。