私は知っていますが、ここにはすでに多くの似たような質問がありますが、それを速くする解決策やそれが遅い理由を見つけられませんでしたか?なぜNetworkStream.Readが遅いのですか?
C#.NETには、同じTCPストリーム(全バイト)で応答するデバイスにTCPを介して通信する必要のあるアプリケーションがあります。メッセージの送信はかなり速くなりますが(約20ms)、NetworkStream.Read()メソッド(または同様のSocket.Receive())を使用してTCPソケットからデータを読み取ると、約600msかかります。 Readメソッドの前にストップウォッチを開始し、Readの直後にストップウォッチを開始することによってこの数値を取得します。
また、トラフィックがWiresharkでログに記録されているので、TCPNoDelayとTCPAckFrequencyレジストリハックを使用して通信がかなり高速になることがわかりましたが、そこに次のメッセージが600ms後に前の答えを読む)。
デバイスは一度に複数のメッセージを処理することはできません。また、独自の確認応答で応答し、最後に送信されたメッセージが受信され、正しく構築されたことを認識します。
ここで確認したいのは、コンソールアプリケーション用のテストコードです。読み込み時に600msの遅延という問題があります。
try
{
if (!retry)
{
Console.WriteLine("Please enter the IP address you want to check:");
ip = Console.ReadLine();
Console.WriteLine("Please enter the port where you want to check on:");
port = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Connecting to {0}: {1}", ip, port);
Console.WriteLine("Please enter the message you want to write to the specified port:");
message = Console.ReadLine();
}
tcp = new TcpClient(ip, port);
tcp.NoDelay = true;
tcp.Client.NoDelay = true;
Stopwatch sWrite = new Stopwatch();
Stopwatch sRead = new Stopwatch();
Stopwatch sDataAvailable = new Stopwatch();
using (NetworkStream ns = tcp.GetStream())
{
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message + "\r");
sWrite.Start();
ns.Write(data, 0, data.Length);
sWrite.Stop();
data = new byte[256];
sRead.Start();
Console.WriteLine("There is data on the socket: {0}", ns.DataAvailable);
int readBytes = ns.Read(data, 0, data.Length);
sRead.Stop();
message = System.Text.Encoding.ASCII.GetString(data, 0, readBytes);
Console.WriteLine(message);
}
Console.WriteLine("The reading speed is {0} and the writing speed is {1}", sRead.ElapsedMilliseconds, sWrite.ElapsedMilliseconds);
}
catch { }
finally
{
tcp.Close();
}
そして、これは、次のような結果与える:私はあなたがそこにあなたの答えを見つけることができると思いThe reading speed is 500 and the writing speed is 0
1行のコードではありませんか? – TomTom
mybeはゆっくりとストリームを書いているデバイスですか? –
私はストリームの読書コードを見て、あなたがこれを見つけることを真剣に疑っています。プログラムの残りの部分、特にスレッドプールスレッドを開始するコードに注目してください。クイックテストは、ThreadPool.SetMinThreads()を呼び出して大きな数値を渡すことです。 –