我们在设计tcp协议时,要传一个字符串过去,报文:头十长度十内容,是否要把‘\0‘也填入,长度是否包含‘\0‘

一句话结论

TCP 是字节流,没有字符串概念;你自定义「头 + 长度 + 内容」的报文:不要把 \0 放进内容区,长度也不包含 \0 。

C语言字符串末尾的 \0 ,只是C语言用来标记字符串结束的标志,不是业务数据本身。网络传输不需要它。

两种方案对比:

✅方案A(推荐,绝大多数私有协议做法)

报文结构: 报文头(固定) + 数据长度N + 数据内容

  • N = 有效字符个数,不含末尾 \0

  • 发送:直接把 "abc" 的 a b c 这3个字节发出去,不追加 \0

  • 接收端:读到长度N,就从后面读取N个字节作为字符串;如果接收端需要C风格字符串,收到之后,在内存里手动追加 \0 ,用于 printf 、字符串函数。

示例:字符串 "abc"

  • 长度字段填:3

  • 内容: 0x61 0x62 0x63

  • 没有 0x00

❌方案B(不推荐)

把 \0 当做数据一起发送,长度包含 \0 。

缺点:

  1. 如果业务字符串中间本身允许包含 \0 (二进制数据),直接就乱套了;

  2. 浪费1字节;

  3. 协议逻辑容易混淆,网络协议一般不依赖 \0 做结束标记。

为什么TCP不能靠 \0 判断结束?

TCP是流式协议,没有消息边界。

如果你靠 \0 去拆分消息:

  • 粘包问题来了:多个字符串粘在一起,解析直接出错;

所以你现在用长度字段分包,才是标准可靠做法。消息边界由长度字段决定,不是 \0 。

示例伪代码(C++)

cpp

std::string str = "abc";

uint32_t len = str.size(); // len = 3,不含'\0'

// 发送:先发len,再发str.data(),不追加'\0'

// 接收端收到后,如果要调用C字符串函数:

char buf100;

read_n(buf, len);

buflen = '\0'; // 接收侧本地补0,方便使用,不通过网络传

简单记忆

\0 是C语言内存里的"字符串终止符",只在本地内存用,不上网线。网络传输的长度,只统计业务有效字符

相关推荐
Ada's9 小时前
【计算机基础系列】003:Python数据结构
开发语言·数据结构·python
2601_9628857210 小时前
如何用 Python 计算 TRIX 三重指数平滑均线指标?
开发语言·python
还卿一钵无情泪10 小时前
Unsloth 微调 构建自己的大模型 没有GPU也能微调
linux·开发语言·人工智能·python·大模型·nlp·unsloth
倔强的石头10612 小时前
应用账号最小权限实践:读写账号、报表账号、运维账号分层
java·运维·开发语言
传人once12 小时前
页面中心圆圈放大效果如何写
开发语言·javascript·ecmascript
NeilYuen12 小时前
【C++】STL源码仿写(二):vector
开发语言·c++
蜗牛互联网12 小时前
Python消费Responses SSE事件:增量文本、超时与取消
java·开发语言·人工智能·后端·python
郝学胜_神的一滴12 小时前
游戏引擎原理与实践 04:拆解引擎基础系统与内存管理
c++·游戏
wanderist.13 小时前
线性筛法详解:从筛质数到欧拉函数、Möbius 函数与约数函数
java·数据结构·算法
All for pursuit.13 小时前
【设计-1】208.实现Trie (前缀树)
数据结构·c++·算法·leetcode