クライアントから文字列を取得して画面に出力する単純なサーバーがあります。また、データを送信して閉じる単純なクライアントもあります。
static void Main()
{
var client = new TcpClient("localhost", 26140);
var stream = client.GetStream();
Byte[] data = System.Text.Encoding.UTF8.GetBytes("CALC qwer");
stream.Write(data, 0, data.Length);
stream.Close();
client.Close();
//Thread.Sleep(100);
}
コメントを外した文字列 'Thread.Sleep(100)' を使用すると、問題なく動作します。しかし、コメントすると、クライアントが文字列を送信しないことがあります (5 ~ 10 回のうち 1 回)。Wireshark と netstat を見て、クライアントが SYN,ACK パッケージを送信し、接続を確立して、何も送信せずにソケットを閉じずに終了することに気付きました。
誰かがこの振る舞いを説明できますか? なぜ睡眠が役立つのですか?私は何を間違っていますか?
更新:
Fox32 に感謝します。
しかし、その後、最初のコードに戻りました。
var client = new TcpClient("localhost", 26140);
client.NoDelay = true;
var stream = client.GetStream();
var writer = new StreamWriter(stream);
writer.WriteLine("CALC qwer");
writer.Flush();
stream.Flush();
stream.Close();
client.Close();
NoDelay を使用しても機能しません。それは悪いです-ネットワークストリーム経由でStreamWriterを使用していますか?
更新:
サーバーコードは次のとおりです。
static void Main(string[] args)
{
(new Server(26140)).Run();
}
サーバークラス:
public void Run()
{
var listener = new TcpListener(IPAddress.Any, port);
listener.Start();
while (true)
{
try
{
var client = listener.AcceptTcpClient();
Console.WriteLine("Client accepted: " + client.Client.RemoteEndPoint);
var stream = client.GetStream();
stream.ReadTimeout = 2000;
byte[] buffer = new byte[1000];
stream.Read(buffer, 0, 1000);
var s = Encoding.UTF8.GetString(buffer);
Console.WriteLine(s);
}
catch (Exception ex)
{
Console.WriteLine("ERROR! " + ex.Message);
}
}
}
更新:
Sleep(1) を追加すると、同時に実行されている 30 ~ 50 のクライアントのうちの 1 つでクラッシュが発生します。そして、Sleep(10) を追加すると完全に解決するようで、クラッシュをキャッチできません。ソケットが正しく閉じるのにこの数ミリ秒が必要な理由がわかりません。