私は C# でクライアント/サーバー アプリケーションを作成していますが、順調に進んでいます。今のところ、すべてが機能しており、非常に堅牢です。私の問題は、接続を介してパケットを送信するときに遅延が発生することです。
クライアント側で私はこれをやっています:
NetworkStream ns = tcpClient.GetStream();
// Send packet
byte[] sizePacket = BitConverter.GetBytes(request.Length);
byte[] requestWithHeader = new byte[sizePacket.Length + request.Length];
sizePacket.CopyTo(requestWithHeader, 0);
request.CopyTo(requestWithHeader, sizePacket.Length);
ns.Write(requestWithHeader, 0, requestWithHeader.Length);
// Receive response
ns.Read(sizePacket, 0, sizePacket.Length);
int responseLength = BitConverter.ToInt32(sizePacket, 0);
byte[] response = new byte[responseLength];
int bytesReceived = 0;
while (bytesReceived < responseLength)
{
int bytesRead = ns.Read(response, bytesReceived, responseLength - bytesReceived);
bytesReceived += bytesRead;
}
(いくつかの例外キャッチなどを省略します。) サーバーは反対のことを行います。つまり、リクエスト全体を取得するまで NetworkStream.Read() でブロックし、それを処理して、Write() を使用して応答を送信します。
Write()/Read() の生の速度は問題ではありません (つまり、大きなパケットの送信は高速です) が、接続を閉じずに複数の小さなパケットを次々に送信すると、非常に遅くなる可能性があります (50 ~ 100 秒の遅延)。 MS)。奇妙なことに、これらの遅延は、通常の ping 時間が 1 ミリ秒未満の LAN 接続で発生しますが、サーバーが localhost で実行されている場合は、ping 時間が実質的に同じであっても発生しません (少なくとも違いはないはずです)。約 100 ミリ秒)。パケットごとに接続を再開し、多くのハンドシェイクを引き起こしている場合、それは私には理にかなっていますが、そうではありません. サーバーが待機状態に入ると、クライアントとの同期が失われ、本質的に失われた接続を再確立するときに少しつまずくようなものです。
それで、私はそれを間違っていますか?サーバーが常にデータを受信できるように、TcpServer と TcpClient 間の接続の同期を維持する方法はありますか? (逆もまた同様です: クライアントからのリクエストの処理に数ミリ秒かかる場合があり、クライアントは Read() でブロックした後にウェイクアップするまで、サーバーからのレスポンスを受信する準備が整っていないように見えます。 .)