TCP侦听器以1024字节切断消息

时间:2011-06-16 15:34:24

标签: c# sockets tcp tcplistener

问题刚刚开始在客户端。这是我收到TCP / IP消息的代码。在我的本地PC上,这个听众收到很多K没问题。我试图增加缓冲区大小,但在客户端网站上,他们仍然报告与之相关的问题..仍然只获得第一个1K(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 个答案:

答案 0 :(得分:7)

我发现你发布的代码没有任何问题将消息提取成字符串,所以我猜其他东西正在发生。

TCP不需要一次性发送您排队的所有数据。这意味着它可以一次发送尽可能少的数据,并且可以选择将数据随意分成多个部分。特别是,如果数据不适合一个数据包,则保证分割您的数据。通常,最大数据包大小(也称为MTU)为1532字节IIRC。

因此,数据发送的可能性很大,但不止一个数据包。接收第一个和第二个数据包之间的延迟可能意味着当第一个数据包到达时,您的代码会愉快地读取它包含的所有内容,然后在第二个数据包有时间到达之前停止(不再有数据)。

您可以通过观察网络流量或允许您的应用从线路中提取更多消息并查看它是否最终获得您发送的所有数据(尽管是碎片)来测试此假设。

最终,潜在的问题是TCP的基本流(而不是基于消息)性质;即使你让这段代码正常工作,也无法保证它将来会继续工作,因为它会对TCP无法保证的东西做出假设。

为了安全起见,您需要合并一个基于消息的结构(例如,在每个数据前面加上4个保持其长度的字节;然后,您可以继续阅读,直到您收到那么多字节为止)。