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

相关推荐
传奇开心果编程1 小时前
【Rust入门练中学】第2课:变量、可变性与常量
开发语言·学习·rust
zr想努力2 小时前
从0开始配置Perforce4环境
开发语言
幸运小圣3 小时前
PointerEvent 常用属性与事件整理【JavaScript】
开发语言·javascript·ecmascript
长谷深风1113 小时前
评测AI Agent:三种裁判各司其职
java·大数据·开发语言·人工智能·ai agent
边境悍匪4 小时前
蜗牛学苑 Java 智能体学习 Day42|项目周开发技术汇总 1 思维导图复盘
java·开发语言·spring boot·学习·spring
君顾14 小时前
本地托管机构管理源码实战:需求拆解、数据建模与多端部署
java·开发语言·托管
青山木4 小时前
Hot 100 --- 最长有效括号
java·数据结构·算法·leetcode·动态规划
传奇开心果编程5 小时前
【Rust入门练中学】 第3课:数据类型
开发语言·学习·rust
泡泡鱼(敲代码中)6 小时前
MySQL 学习笔记:DCL、函数与约束 —— 安全、效率、完整性的三板斧
开发语言·笔记·sql·学习·mysql·gitee