Почему NetworkStream.Read такой медленный? - PullRequest
4 голосов
/ 13 марта 2012

Я знаю, здесь уже есть много подобных вопросов, но я не нашел решения, чтобы сделать это быстрее или причина, почему это так медленно?

У нас есть приложение на C # .NET, которое должно обмениваться данными через TCP с устройством, которое отвечает в том же потоке TCP (все в байтах). Отправка сообщений происходит довольно быстро (около 20 мс), но когда мы читаем данные из сокета TCP с помощью метода NetworkStream.Read () (или аналогичного метода Socket.Receive ()), это занимает около 600 мс. Я получаю это число, запуская секундомер до чтения, и останавливаю его сразу после чтения.

Я также регистрирую трафик с помощью Wireshark, и там я вижу, что связь идет довольно быстро (с помощью хаков реестра TCPNoDelay и TCPAckFrequency), но там я увидел, что следующее сообщение, отправленное на устройство, происходит через 600 мс (после чтения предыдущего ответа).

Устройства не могут обрабатывать несколько сообщений одновременно, и они также отвечают заказным подтверждением, чтобы наша программа знала, что последнее отправленное сообщение получено и построено правильно.

Хорошо, вот некоторый тестовый код, который у меня есть для консольного приложения, и даже при этом возникает проблема задержки чтения 600 мс.

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

Ответы [ 2 ]

2 голосов
/ 07 июня 2012

Я только что нашел решение своей проблемы с медленной сетью и хочу поделиться ею со всеми вами.Вы никогда не знаете, когда или кто может столкнуться с той же проблемой.Ранее в этот день я зашел на этот сайт TcpClient с задержкой получения более 500 мс , и там я последовал за решением взлома реестра для бита PSH (IgnorePushBitOnReceives), и это решило ее.Таким образом, у нас теперь есть временная быстрая связь, потому что я думаю, что люди, с которыми мы работаем, просто должны установить флаг Push для TCP-сообщений.

0 голосов
/ 13 марта 2012

Я думаю, что вы можете найти свой ответ там:

NetworkStream Read Slowness

Просто попробуйте изменить размер буфера, и он должен работать быстрее.

Вам также следует попытаться использовать Microsoft Network Monitor, чтобы увидеть, что происходит за вашей проблемой.

...