01 TCP 协议是流式协议

发布时间:2026/6/30 1:42:17
01 TCP 协议是流式协议 很多读者从接触网络知识以来应该听说过这句话TCP 协议是流式协议。那么这句话到底是什么意思呢所谓流式协议即协议的内容是像流水一样的字节流内容与内容之间没有明确的分界标志需要我们人为地去给这些协议划分边界。举个例子A 与 B 进行 TCP 通信A 先后给 B 发送了一个 100 字节和 200 字节的数据包那么 B 是如何收到呢B 可能先收到 100 字节再收到 200 字节也可能先收到 50 字节再收到 250 字节或者先收到 100 字节再收到 100 字节再收到 200 字节或者先收到 20 字节再收到 20 字节再收到 60 字节再收到 100 字节再收到 50 字节再收到 50 字节......不知道读者看出规律没有规律就是 A 一共给 B 发送了 300 字节B 可能以一次或者多次任意形式的总数为 300 字节收到。假设 A 给 B 发送的 100 字节和 200 字节分别都是一个数据包对于发送端 A 来说这个是可以区分的但是对于 B 来说如果不人为规定多长为一个数据包B 每次是不知道应该把收到的数据中多少字节作为一个有效的数据包的。而规定每次把多少数据当成一个包就是协议格式规范的内容之一。经常会有新手写出类似下面这样的代码发送端//...省略创建socket建立连接等部分不相关的逻辑... char buf[] the quick brown fox jumps over a lazy dog.; int n send(socket, buf, strlen(buf), 0); //...省略出错处理逻辑...接收端//省略创建socket建立连接等部分不相关的逻辑... char recvBuf[50] { 0 }; int n recv(socket, recvBuf, 50, 0); //省略出错处理逻辑... printf(recvBuf: %s, recvBuf);为了专注问题本身的讨论我这里省略掉了建立连接和部分错误处理的逻辑。上述代码中发送端给接收端发送了一串字符”the quick brown fox jumps over a lazy dog.“接收端收到后将其打印出来。类似这样的代码在本机一般会工作的很好接收端也如期打印出来预料的字符串但是一放到局域网或者公网环境就出问题了即接收端可能打印出来字符串并不完整如果发送端连续多次发送字符串接收端会打印出来的字符串不完整或出现乱码。不完整的原因很好理解即对端某次收到的数据小于完整字符串的长度recvBuf 数组开始被清空成 0收到部分字符串后该字符串的末尾仍然是 0printf 函数寻找以 0 为结束标志的字符结束输出乱码的原因是如果某次收入的数据不仅包含一个完整的字符串还包含下一个字符串部分内容那么 recvBuf 数组将会被填满printf 函数输出时仍然会寻找以 0 为结束标志的字符结束输出这样读取的内存就越界了一直找到为止而越界后的内存可能是一些不可读字符显示出来后就乱码了。我举这个例子希望你明白 能对TCP 协议是流式协议有一个直观的认识。正因为如此所以我们需要人为地在发送端和接收端规定每一次的字节流边界以便接收端知道从什么位置取出多少字节来当成一个数据包去解析这就是我们设计网络通信协议格式的要做的工作之一。