Tech Racho エンジニアの「?」を「!」に。
  • インフラ

[C#] TcpListenerのSystem.Net.Sockets.Socket.AvailableでTCPサーバを書くときの注意

C#のTcpListenerを使って、サーバを作っていています。

System.Net.Sockets.Socket.Available プロパティは、信用してはいけません。
下のコードは、クライアントから接続があってもたまにしか受信できません。

うまく動かないコード

using (Socket client = listener.AcceptSocket())
{
  //ここにThread.Sleep(1000)とかを入れるとうまく動くことも多い・・・

  while (client.Available) //ここでいきなりfalseが返ってくる
  {
    byte[] buf = new byte[256];
    client.Receive(buf);
    Console.WriteLine(Encoding.ASCII.GetString(buf));
  }
}

正しいコード

この場合、次のようにするのが正しいです。

using (Socket client = listener.AcceptSocket())
{
  byte[] buf = new byte[256];
  int bytes;
  while ((bytes = client.Receive(buf)) > 0)
  {
    Console.WriteLine(Encoding.ASCII.GetString(buf));
  }
}

それから、TcpListenerのコンストラクタは第一引数にローカルIPアドレス、第二引数にポート番号を渡しますが、サーバの場合は

TcpListener listener = new TcpListener(IPAddress.Any, 45678);

のように IPAddress.Any を渡すのが正しいです。「ローカルIPアドレス」といっても、サーバマシンのアドレスではなく、クライアントのアドレスを渡します。わかりにくい。。


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。