我们在设计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语言内存里的"字符串终止符",只在本地内存用,不上网线。网络传输的长度,只统计业务有效字符

相关推荐
揽星河..7 分钟前
【初阶数据结构】常见的排序算法
数据结构·排序算法·1024程序员节
孙鹏宇.23 分钟前
C++类型转换
c++
超级架构师36 分钟前
让 COBOL 长出 AI 大脑:原生 Agent 核心框架 praxo-core 深度剖析
c语言·开发语言·c++·人工智能·python·架构·ai编程
·present·40 分钟前
CSAPP(lecture 10)
c语言·c++
Non-existent98741 分钟前
在 WPS/Excel 里做地理数据处理:功能市场 + 奥维 / Google Earth / QGIS 三种跳转实战
开发语言·javascript·ecmascript
YLCHUP1 小时前
【模拟&STL】题解:AT_abc203_e [ABC203E] White Pawn_基础算法_数据结构_STL模板库_AtcoderABC_C++算法竞赛
数据结构·c++·算法·leetcode·动态规划·哈希算法·近邻算法
啊啊啊啊啊!!!!1 小时前
【c++】⽤哈希表封装myunordered_map和myunordered_set
数据结构·哈希算法·散列表
xiaolang_8616_wjl1 小时前
c++游戏_宝可梦大世界(源代码)
开发语言·c++·游戏
(●—●)橘子……1 小时前
力扣 第525场周赛 练习理解
数据结构·python·学习·算法·leetcode
Tt有了t1 小时前
Redis的数据结构
数据结构·数据库·redis