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

如何对通过TCP协议发送的数据进行标记?

在TCP协议中标记发送数据的实用方案

我完全懂你的困惑——HTTP本身是基于TCP的,但它帮我们封装好了请求头、内容长度这些规则,所以我们不用操心数据边界的问题。但直接用TCP的话,就得自己搞定「怎么让对方知道一段数据从哪开始到哪结束」,这才是核心问题。

下面是几种工业界实际在用的解决方案,帮你搞定数据标记的问题:

1. 固定长度法

如果你的数据长度是固定的,这是最简单的方案。比如约定每次发送的数据都是1024字节,不足的部分用空字节或者特定填充符补全。接收方每次固定读取指定长度的字节即可。

示例代码(Python):

# 发送端:将数据填充到16字节长度
data = "hello tcp".encode()
padded_data = data.ljust(16, b'\x00')  # 用空字节填充
sock.sendall(padded_data)

# 接收端:固定读取16字节,再去掉填充符
received = sock.recv(16).strip(b'\x00').decode()

2. 长度前缀法(最推荐)

这是处理可变长度数据的标准方案,也是HTTP等协议底层常用的思路。发送时先传一个固定长度的“长度标识”(比如4字节的整数),告诉接收方接下来要接收的数据有多长;接收方先读取这个长度,再根据长度读取对应字节数的实际内容。

这种方法灵活可靠,特别适合发送JSON这类长度不固定的数据。

示例代码(Python):

import struct

# 发送端:先打包数据长度,再发送JSON内容
json_content = '{"name": "Alice", "age": 30}'.encode()
# 用struct把长度打包成4字节大端整数(!I表示网络字节序的无符号整数)
length_prefix = struct.pack('!I', len(json_content))
sock.sendall(length_prefix + json_content)

# 接收端:先读取长度前缀,再读取对应长度的数据
prefix = sock.recv(4)
data_length = struct.unpack('!I', prefix)[0]
received_json = sock.recv(data_length).decode()

3. 分隔符法

约定一个不会出现在实际数据中的特殊分隔符(比如自定义的###END###,或者HTTP里的\r\n\r\n),发送方在数据末尾加上分隔符;接收方持续读取字节,直到遇到分隔符为止,再截断分隔符得到原始数据。

⚠️ 注意:一定要确保分隔符不会被数据本身包含,否则会导致接收方提前截断数据,出现错误。

示例代码(Python):

# 发送端:在JSON数据后添加分隔符
json_content = '{"name": "Bob"}'.encode()
sock.sendall(json_content + b'###END###')

# 接收端:循环读取直到找到分隔符
buffer = b''
while b'###END###' not in buffer:
    chunk = sock.recv(1024)
    if not chunk:  # 连接断开
        break
    buffer += chunk
# 分割出原始数据
received_json = buffer.split(b'###END###')[0].decode()

其实你熟悉的HTTP协议,就是用了「长度前缀(Content-Length头)」或者「分块传输(Transfer-Encoding: chunked)」的方式来标记数据边界的。如果要发送JSON,优先选长度前缀法,既简单又不容易出问题。

内容的提问来源于stack exchange,提问作者Nicke7117

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 03:27:31