TCP слушатель режет сообщение на 1024 байта - PullRequest
5 голосов
/ 16 июня 2011

Проблема только началась на стороне клиента. Вот мой код, где я получаю сообщение TCP / IP. На моем локальном ПК этот слушатель получает много K без проблем. Я пытался увеличить размер буфера, но на клиентском сайте они по-прежнему сообщают о проблемах, связанных с ним .. Все еще получают только первые 1 КБ (1024 байта)

public void Start()
{
  //Define TCP listener
  tcpListener = new TcpListener(IPAddress.Any, IDLocal.LocalSession.PortNumber);

  try
  {
    //Starting TCP listenere
    tcpListener.Start();

    while (true)
    {
      var clientSocket = tcpListener.AcceptSocket();
      if (clientSocket.Connected)
      {
        var netStream = new NetworkStream(clientSocket);

        // Check to see if this NetworkStream is readable.
        if (netStream.CanRead)
        {
          var myReadBuffer = new byte[1024];
          var myCompleteMessage = new StringBuilder();

          // Incoming message may be larger than the buffer size.
          do
          {
            var numberOfBytesRead = netStream.Read(myReadBuffer, 0, myReadBuffer.Length);
            myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
          } while (netStream.DataAvailable);

          //All we do is response with "OK" message
          var sendBytes = Encoding.ASCII.GetBytes("OK");
          netStream.Write(sendBytes, 0, sendBytes.Length);

          clientSocket.Close();
          netStream.Dispose();

          // Raise event with message we received
          DataReceived(myCompleteMessage.ToString());
        }
      }
    } 
  }
  catch (Exception e)
  {
    //If we catch network related exception - send event up
    IDListenerException(e.Message);  
  }
}

1 Ответ

7 голосов
/ 16 июня 2011

Я не вижу проблем с кодом, который вы опубликовали для извлечения сообщения в строку, поэтому я предполагаю, что что-то еще происходит.

TCP не требуется для отправки всех данных, которые выочередь к нему за один раз.Это означает, что он может отправлять столько раз, сколько он хочет, и может разделить ваши данные на части по желанию.В частности, гарантированно разделяет ваши данные, если они не помещаются в один пакет.Как правило, максимальный размер пакета (он же MTU) составляет 1532 байта IIRC.

Поэтому существует реальная вероятность того, что данные отправляются, но в виде более одного пакета.Задержка между приемом первого и второго пакетов может означать, что при поступлении первого из них ваш код успешно читает все, что в нем содержится, а затем останавливается (больше никаких данных), прежде чем второй пакет успеет прибыть.

Выможно проверить эту гипотезу, наблюдая за сетевым трафиком или позволяя вашему приложению получать больше сообщений из сети и посмотреть, получит ли оно, наконец, все отправленные вами данные (хотя бы по частям).

В конечном итоге основная проблема заключается в том, чтоФундаментальная основанная на потоках (а не на сообщениях) природа TCP;даже если вы заставите этот код работать правильно, нет никакой гарантии, что он продолжит работать в будущем , потому что он делает предположения о вещах, которые не гарантирует TCP.

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

...