当前位置: 首页 > news >正文

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,收到部分字符串后,该字符串的末尾仍然是 0,printf 函数寻找以 0 为结束标志的字符结束输出;乱码的原因是如果某次收入的数据不仅包含一个完整的字符串,还包含下一个字符串部分内容,那么 recvBuf 数组将会被填满,printf 函数输出时仍然会寻找以 0 为结束标志的字符结束输出,这样读取的内存就越界了,一直找到为止,而越界后的内存可能是一些不可读字符,显示出来后就乱码了。

我举这个例子希望你明白 能对TCP 协议是流式协议有一个直观的认识。正因为如此,所以我们需要人为地在发送端和接收端规定每一次的字节流边界,以便接收端知道从什么位置取出多少字节来当成一个数据包去解析,这就是我们设计网络通信协议格式的要做的工作之一。

http://www.jsqmd.com/news/1093063/

相关文章:

  • Lean 4实战指南:5个步骤掌握下一代定理证明编程语言
  • Fatal error: require(): Failed opening required...” 以及如何彻底避免它再次出现
  • 2026年AI Agent大爆发!小白程序员必看:收藏这份从入门到精通指南,抓住时代红利!
  • 5个技巧轻松解决经典游戏兼容问题:开源dxwrapper完全指南
  • Vibe Coding:说人话就能做软件,超简单开发流程全讲明白
  • Netty 高性能网络编程:从零构建高并发服务器
  • 【TSP问题】基于帝企鹅算法AFO求解单仓库多旅行商问题MTSP附Matlab代码
  • XSS防御实战:从同源策略到CSP的纵深安全体系构建
  • Kafka2.4-Windows安装教程
  • 无需同看同一张图:跨被试神经表征对齐的VAE新范式
  • 一文吃透Java IO流!从底层原理到实战代码(新手必看)
  • 只有 B 级能力的大模型,怎么干出 A 级的活?
  • 续流二极管:电机断电瞬间的“高压泄洪道”
  • 容器化 Java 应用 CPU 使用率监控口径解析:node exporter vs cAdvisor vs JMX
  • 工程项目过程留痕管理的3个断点与5款软件选型对比
  • 02 状态(State)
  • 多发射器识别技术(SMEI)在无线通信安全中的应用
  • Ubuntu 下用 udev 固定 PX4 飞控 USB 设备名
  • AI大模型学习指南:Agent、MCP、Skill全解析,小白也能轻松收藏掌握
  • 如何高效捕获网页媒体资源:猫抓浏览器扩展的完整指南
  • 从Prompt到Harness:AI工程的三层进化,小白也能轻松掌握,建议收藏!
  • 豆包牛批普拉斯
  • 从多项式回归到“水平直线”:Matplotlib 绘图中的 NumPy 数组维度隐患
  • 汇编中寄存器寻址与立即数寻址混淆问题解决
  • Linux命令-quota(显示用户磁盘配额)
  • Matlab 麻雀优化双向长短期记忆网络(SSA-BILSTM)的时间序列预测(时序)
  • 京东抢购助手终极指南:免费开源工具实现自动化抢单
  • 2026证件照换衣服工具全解:手机APP、在线网页、小程序操作指南
  • RAG 搞定!告别「有库无答」,用 Rerank 让大模型精准回复(收藏版)
  • 别一上来就看复杂插件:先用 Delay看懂一个最小 VM 插件是怎么接进系统的