You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让TcpClient每次对应conn.sendall()仅接收单条消息?

问题根源

TCP 是流式传输协议,它不会为你划分消息边界。服务端多次调用sendall发送的内容,可能被TCP协议合并成一个数据包发送,或者客户端一次Read操作读到了多个数据包的内容——这就是所谓的「粘包」问题,导致你收到多条消息的合并内容。

解决方案:添加消息分隔符

最适合你当前场景的方案是给每条消息添加一个唯一的分隔符(比如换行符\n),服务端发送时在每条消息末尾加上分隔符,客户端读取时按分隔符拆分,只处理完整的单条消息。

修改Python服务端代码

在发送的字符串末尾添加换行符,确保每条消息都有明确的边界:

# 原代码:conn.sendall(val.encode('utf-8'))
# 修改为:
conn.sendall((val + '\n').encode('utf-8'))

修改C#客户端代码

客户端需要维护一个缓存来存储未处理的不完整消息,每次读取后拆分出完整的消息进行处理:

// 在类中添加全局缓存变量
private string _unprocessedData = string.Empty;

void tt_Tick(object sender, EventArgs e)
{
    NetworkStream DataStream = client.GetStream();
    byte[] buffer = new byte[client.ReceiveBufferSize];
    int bytesRead = DataStream.Read(buffer, 0, client.ReceiveBufferSize);
    
    if (bytesRead > 0)
    {
        // 将读取到的内容追加到缓存
        _unprocessedData += Encoding.UTF8.GetString(buffer, 0, bytesRead);
        
        // 按换行符拆分所有完整消息
        string[] completeMessages = _unprocessedData.Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries);
        
        // 处理每条完整消息
        foreach (string msg in completeMessages)
        {
            // 这里可添加坐标解析逻辑,示例:
            // string[] coords = msg.Split(',');
            // double x = double.Parse(coords[0]);
            // double y = double.Parse(coords[1]);
            DrawDubble(CreateGraphics());
        }
        
        // 更新缓存,只保留未处理的不完整部分
        if (_unprocessedData.EndsWith("\n"))
        {
            _unprocessedData = string.Empty;
        }
        else
        {
            int lastNewLineIndex = _unprocessedData.LastIndexOf('\n');
            _unprocessedData = _unprocessedData.Substring(lastNewLineIndex + 1);
        }
    }
}

方案说明

  • 服务端的换行符明确标记了消息边界,无论TCP如何合并数据包,客户端都能通过拆分\n识别单条消息。
  • 缓存_unprocessedData用来处理「一次读取到部分消息」的情况,比如某次只读到了35,12,(1,这部分内容会留在缓存里,等下次读取到剩余部分后再合并处理。

内容的提问来源于stack exchange,提问作者The Limit Breaker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:57:11