私はクライアントとサーバーの2つの部分を持っています。そして、クライアントからサーバーにデータ(サイズ> 5840バイト)を送信しようとすると、サーバーからデータが返されます。私はこれを毎回何回も待っています。ランダム "既存の接続はリモートホストによって強制的に閉じられました。" TCPリセット後
Unhandled Exception: System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. --->
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 s ize)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 s ize)
at TCP_Server.Program.Main(String[] args)
クライアントコード(これはループ内で):
try
{
Int32 port = 13777;
using (TcpClient client = new TcpClient(ip, port))
using (NetworkStream stream = client.GetStream())
{
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
var data = GenerateData(size);
sw.Start();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
// Buffer to store the response bytes.
data = new Byte[size];
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
sw.Stop();
Console.WriteLine(i + ": Done transporting " + size + " bytes to and from " + ip + " time: " +
sw.ElapsedMilliseconds + " ms");
// Close everything.
stream.Close();
client.Close();
}
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
sw.Reset();
Serverコード:
Byte[] bytes = new Byte[size];
// Enter the listening loop.
for (int i = 0; i < numberOfPackages; i++)
{
using (TcpClient client = server.AcceptTcpClient())
using (NetworkStream stream = client.GetStream())
{
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
// Loop to receive all the data sent by the client.
while ((stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Send back a response.
stream.Write(bytes, 0, size);
}
client.GetStream().Close();
client.Close();
}
Console.WriteLine("Receive data size " + size);
}
私はいつかサーバアプリケーションのクラッシュ、クラッシュがエラー非常にランダムなようですwiresharkを使用して送信されたtcpパッケージを監視し、プログラムがクラッシュする前にクライアントからサーバーにTCP RSTが送信されたことを確認しました。だから私は問題は、RSTが正しく処理されていないと仮定します。 クライアントとホストの間にファイアウォールがないため、問題はありません。
クライアントとサーバの両方のためのwiresharkのファイルはここにある:https://www.dropbox.com/sh/ctl2chq3y2c20n7/AACgIJ8IRiclqnyOyw8sqd9La?dl=0
だから、どちらか私はTCP RSTを取り除く必要があるか、私はいくつかの方法でそれを処理し、クラッシュしないように自分のサーバーを必要としています。
私は長い待ち時間を使用しようとしましたが、それは役に立ちません。 データが5840バイト未満の場合は、私が知っているクラッシュはありません。
ご意見やご提案はありますか?
編集:私はそれは次のように変更して動作するようになったの答えに ありがとう:
サーバー:
// Loop to receive all the data sent by the client.
int k = 0;
while (k < size)
{
int bytesRead = stream.Read(bytes, 0, bytes.Length);
k += bytesRead;
}
// Send back a response.
stream.Write(bytes, 0, size);
そして、クライアント側で受信したときと同じ。私は最初にすべてのデータを送信してから、サーバーが自分のアプリケーションに対してこの作業に応答するようにしたいからです。
ありがとうございました!!! 私はアプリケーションを送信し、受信し、同時に実行しないので、最初の問題を修正する必要がありました。 – TobiasW
@TobiasWあなたはデッドロックの問題を理解していないと思います。このコードはランダムにデッドロックします。 100MBを送信しようとすると、デッドロックが発生します。 – usr
最初にクライアントからすべてを送信しても、サーバーはすべてを受信してから送信します。この後、私は待って、すべてをやり直す。このコードは実際には使用されておらず、ベンチマークアプリケーションのほうが多いです。 – TobiasW