c# - TCP 监听器将消息剪切为 1024 字节

标签 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);  
  }
}

最佳答案

我没有看到您发布的用于将消息提取到字符串中的代码有任何问题,所以我猜测还有其他事情正在发生。

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

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

您可以通过观察网络流量或允许您的应用从线路中提取更多消息并查看它是否最终确实获得了您发送的所有数据(尽管是分段的)来检验这个假设。

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

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

关于c# - TCP 监听器将消息剪切为 1024 字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6374484/

相关文章:

node.js - 套接字超时!使用 Node telnet-client 的 Telnet 连接问题

linux - NFS 实现,ubuntu 发送空的 nfs_fh3?

transactions - 是否可以通过机器边界(通过 tcp-ip)进行交易?

tcp - 原始 tcp 发送和接收

c# - 嵌套的 Math.Pow(...) 行为怪异

c# - 在 AutoCAD 中绘制表格

c# - 获取所有方法调用

c# - C#通用扩展方法可编译但无法使用?

java - HTML5 Websocket 错误

c# - 抛出的异常似乎阻塞了其他线程