TCP是面向字节流的协议
TCP字节流
之所以会说 TCP 是面向字节流的协议,UDP 是面向报文的协议,是因为操作系统对 TCP 和 UDP 协议的发送方的机制不同,也就是问题原因在发送方。
为什么 UDP 是面向报文的协议?
当用户消息通过 UDP 协议传输时,操作系统不会对消息进行拆分,在组装好 UDP 头部后就交给网络层来处理,所以发出去的 UDP 报文中的数据部分就是完整的用户消息,也就是每个 UDP 报文就是一个用户消息的边界,这样接收方在接收到 UDP 报文后,读一个 UDP 报文就能读取到完整的用户消息。
你可能会问,如果收到了两个 UDP 报文,操作系统是怎么区分开的?
操作系统在收到 UDP 报文后,会将其插入到队列里,队列里的每一个元素就是一个 UDP 报文,这样当用户调用 recvfrom() 系统调用读数据的时候,就会从队列里取出一个数据,然后从内核里拷贝给用户缓冲区。

为什么 TCP 是面向字节流的协议?
当用户消息通过 TCP 协议传输时,消息可能会被操作系统分组成多个的 TCP 报文,也就是一个完整的用户消息被拆分成多个 TCP 报文进行传输。
这时,接收方的程序如果不知道发送方发送的消息的长度,也就是不知道消息的边界时,是无法读出一个有效的用户消息的,因为用户消息被拆分成多个 TCP 报文后,并不能像 UDP 那样,一个 UDP 报文就能代表一个完整的用户消息。
在发送端,当我们调用 send 函数完成数据“发送”以后,数据并没有被真正从网络上发送出去,只是从应用程序拷贝到了操作系统内核协议栈中。
至于什么时候真正被发送,取决于发送窗口、拥塞窗口以及当前发送缓冲区的大小等条件。也就是说,我们不能认为每次 send 调用发送的数据,都会作为一个整体完整地消息被发送出去。
我们不能认为一个用户消息对应一个 TCP 报文,正因为这样,所以 TCP 是面向字节流的协议。
当两个消息的某个部分内容被分到同一个 TCP 报文时,就是我们常说的 TCP 粘包问题,这时接收方不知道消息的边界的话,是无法读出有效的消息。
要解决这个问题,要交给应用程序
粘包
粘包的问题出现是因为不知道一个用户消息的边界在哪,如果知道了边界在哪,接收方就可以通过边界来划分出有效的用户消息。
一般有三种方式分包的方式:
固定长度的消息;
特殊字符作为边界;
自定义消息结构。
固定长度的消息
这种是最简单方法,即每个用户消息都是固定长度的,比如规定一个消息的长度是 64 个字节,当接收方接满 64 个字节,就认为这个内容是一个完整且有效的消息。
但是这种方式灵活性不高,实际中很少用。
特殊字符作为边界
可以在两个用户消息之间插入一个特殊的字符串,这样接收方在接收数据时,读到了这个特殊字符,就把认为已经读完一个完整的消息。
HTTP 是一个非常好的例子。

HTTP 通过设置回车符、换行符作为 HTTP 报文协议的边界。
有一点要注意,这个作为边界点的特殊字符,如果刚好消息内容里有这个特殊字符,我们要对这个字符转义,避免被接收方当作消息的边界点而解析到无效的数据。
自定义消息结构
可以自定义一个消息结构,由包头和数据组成,其中包头包是固定大小的,而且包头里有一个字段来说明紧随其后的数据有多大。
比如这个消息结构体,首先 4 个字节大小的变量来表示数据长度,真正的数据则在后面。
struct { u_int32_t message_length; char message_data[];
} message;
当接收方接收到包头的大小(比如 4 个字节)后,就解析包头的内容,于是就可以知道数据的长度,然后接下来就继续读取数据,直到读满数据的长度,就可以组装成一个完整到用户消息来处理了。
相关文章:
TCP是面向字节流的协议
TCP字节流 之所以会说 TCP 是面向字节流的协议,UDP 是面向报文的协议,是因为操作系统对 TCP 和 UDP 协议的发送方的机制不同,也就是问题原因在发送方。 为什么 UDP 是面向报文的协议? 当用户消息通过 UDP 协议传输时,…...
读书笔记——《when breath becomes air》《超越自卑》
为啥要两本书一起写读后感? 读完这两本书本来应该分开来写点东西的,不过我认为这两本书应该写不了太多内容。虽然我也看了几本英文原著(也写了点东西),但是我明显低估了《when breath becomes air》的难度,…...
CMD与DOS脚本编程【第二章】
预计更新 第一章. 简介和基础命令 1.1 介绍cmd/dos脚本语言的概念和基本语法 1.2 讲解常用的基础命令和参数,如echo、dir、cd等 第二章. 变量和运算符 2.1 讲解变量和常量的定义和使用方法 2.2 介绍不同类型的运算符和运算规则 第三章. 控制流程和条件语句 3.1 介…...
面试字节,过关斩将直接干到 3 面,结果被吊打了?
人人都有大厂梦,对于软件测试员来说,BAT 为首的一线互联网公司肯定是自己的心仪对象,毕竟能到这些大厂工作,不仅薪资高待遇好,而且能力技术都能够得到提升,最关键的是还能够给自己镀上一层金,让…...
OpenCV在iOS端的集成及Mat和UIImage互相转化(附源码)
OpenCV是一个非常强大的图形处理框架,可以运行在Linux、Windows、Android和Mac OS操作系统上,在自动驾驶、智能家居、人脸识别、图片处理等方面提供了非常丰富且功能强大的api,在图片处理方便,基本上可以满足对图片处理的所有需求…...
5月跳槽会有风险,不跳也会有?
今天讲讲跳槽。 说实话跳槽是为了寻求更好的发展,但在跳槽前我们也不能确定下家就是更好的归宿,这就更加需要我们审慎地去对待,不能盲目跳槽。 其次,我们离职和跳槽,其中的原因很大一部分是目前薪资不符合预期。 那…...
【小白版】最简单的 goland package 教程包括自定义包的使用
一、Hello World 最简单的教程,就需要从最简单的事情开始说起: mkdir myappcd myappgo mod init myapp // myapp是主项目名 这行命令将生成一个go.mod文件,这个文件会记录所有的包的依赖关系,一个空的go.mod只有项目名称和go版本…...
IMX6ULL的I2C驱动详细分析
IMX6ULL的I2C驱动详细分析 文章目录 IMX6ULL的I2C驱动详细分析i2c_imx_driver 的平台驱动注册i2c_imx_probe注册函数i2c_imx_algoI2C算法结构体i2c_imx_start开始I2Ci2c_imx_stop停止I2Ci2c_imx_isr中断服务函数i2c_imx_dma_writeDMA 进行写操作的 I2C 传输2c_imx_dma_readi2c_…...
日志迁移到 logback
目标 本次迁移的目标就是用 slf4jlogback 的日志框架来取代目前的 slf4jlog4j 如何迁移 基于 slf4j 的无痛迁移 项目本身是采用的 slf4jlog4j 日志架构,所以迁移到 logback 基本无痛 修改依赖 原本是 slf4jlog4,依赖如下 <dependency><gro…...
开源字节 CRM 系统
开源字节CRM是一款SaaS模式的客户关系管理软件,基于钉钉平台进行研发,以客户管理为核心,包含客户管理、销售全流程管理,合同订单、工单管理、移动审批、数据分析六大模块。 旨在助力企业销售全流程精细化、数字化管理,…...
七、Spring Cloud Alibaba-Sentinel
一、引言 1、了解服务可用性问题,服务挂掉原因 缓存击穿、单点故障、流量激增、线程池爆满、CPU飙升、DB超时、缺乏容错机制或保护机制、负载不均、服务雪崩、异常没处理等。 服务雪崩效应:因服务提供者的不可用导致服务调用者的不可用,并将…...
机器学习与深度学习——通过knn算法分类鸢尾花数据集iris求出错误率并进行可视化
什么是knn算法? KNN算法是一种基于实例的机器学习算法,其全称为K-最近邻算法(K-Nearest Neighbors Algorithm)。它是一种简单但非常有效的分类和回归算法。 该算法的基本思想是:对于一个新的输入样本,通过…...
【MySQL】MySQL基础知识详解
文章目录 1. MySQL概述1.1 数据库相关概念1.1.1 数据库、数据库管理系统与SQL1.1.2 关系型数据库与数据模型 1.2 MySQL数据库1.2.1 MySQL的安装与配置1.2.2 MySQL服务的启动与停止1.2.3 连接MySQL服务端 2. SQL2.1 SQL简介2.2 DDL2.2.1 数据库操作2.2.2 表操作2.2.2.1 创建表2.…...
RabbitMQ日常使用小结
一、使用场景 削峰、解耦、异步。 基于AMQP(高级消息队列协议)协议来统一数据交互,通过channel(网络信道)传递信息。erlang语言开发,并发量12000,支持持久化,稳定性好,集群不支持动态扩展。 RabbitMQ的基本概念 二、组成及工作流…...
博物馆文物馆藏环境空气质量无线监控系统方案
博物馆文物馆藏环境空气质量无线监控系统方案 博物馆无线环境测控系统 博物馆恒温恒湿消毒净化系统 现代化博物馆空气质量一体化3D可视化管控平台 博物馆温湿度在线监控系统 博物馆光照在线监控系统 博物馆二氧化碳在线监控系统 博物馆在线监控系统 博物馆紫外线在线监控…...
测试理论----Bug的严重程度(Severity)和优先级(Priority)的分类
【原文链接】测试理论----Bug的严重程度(Severity)和优先级(Priority)的分类 一、Bug的严重程度(Severity) Bug的Severity(严重程度)指的是一个Bug对软件系统功能影响的程度&#…...
斯坦福、Nautilus Chain等联合主办的 Hackathon 活动,现已接受报名
由 Stanford Blockchain Accelerator、Zebec Protocol、 Nautilus Chain、Rootz Lab 共同主办的黑客松活动,现已接受优秀项目提交参赛申请。 在加密行业发展早期,密码极客们就始终在对区块链世界基础设施,在发展方向的无限可能性进行探索。而…...
00后卷王,把我们这些老油条卷的辞职信都写好了........
现在的小年轻真的卷得过分了。 前段时间我们公司来了个00年的,工作没两年,跳槽到我们公司起薪18K,都快接近我了。 后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了。 最近和他聊了一次天,原来这位小老弟家…...
JavaEE(系列12) -- 常见锁策略
目录 1. 乐观锁和悲观锁 2. 轻量级锁与重量级锁 3. 自旋锁和挂起等待锁 4. 互斥锁和读写锁 5. 可重入锁与不可重入锁 6. 死锁 6.1 死锁的必要条件 6.2 如何避免死锁 7. 公平锁和非公平锁 8. Synchronized原理及加锁过程 8.1 Synchronized 小结 8.2 加锁工作过程 8.2.1 偏向锁…...
前端nginx接口跨域
前提:vue项目本地接口通过proxy都可使用,但是项目部署在服务器上后发现所有接口出现503如下状况 简而言之:页面部署在域名为https://aa.bb.cc.com/vehicle/#/下,但是我接口需访问的是https:// azz.qqv.com/permission/company/gro…...
告别GRUB安装失败:Ubuntu 22.04单硬盘安装最全避坑指南(MBR/EFI详解)
Ubuntu 22.04单硬盘安装终极指南:从MBR到UEFI的GRUB避坑手册当你满怀期待地将Ubuntu 22.04安装U盘插入电脑,却在最后关头遭遇"无法将GRUB安装到/dev/sda"的红色警告时,那种挫败感我深有体会。这不是简单的安装失败,而是…...
特征函数损失:频域视角解决机器学习分布偏移问题
1. 项目概述在机器学习项目的实际落地过程中,我们常常会遇到一个令人头疼的“幽灵”:模型在精心准备的训练集上表现优异,但一到真实的生产环境,性能就出现断崖式下跌。这个幽灵就是“分布偏移”。无论是计算机视觉、自然语言处理还…...
手把手教你用Linux命令‘偷看’UEFI启动日志,排查系统启动失败问题
实战指南:用Linux命令深度解析UEFI启动日志当你的Linux系统卡在启动界面,或是反复重启无法进入桌面时,那种焦虑感每个运维人员都深有体会。UEFI启动过程就像一场精心编排的交响乐,任何一个环节出错都可能导致系统启动失败。本文将…...
Unity源码级优化:IL织入、Native桥接与内存重排实战
1. 这不是“性能调优指南”,而是一份引擎级手术记录Unity项目优化,市面上90%的教程止步于“Profiler看CPU/GPU帧耗→查DrawCall→合批→减Shader复杂度→压贴图”。我干了八年Unity底层支持,给二十多个中大型项目做过深度介入,发现…...
安全稀疏矩阵乘法:基于二叉树递归传播的MPC算法优化详解
1. 项目概述:当稀疏矩阵乘法遇上安全多方计算 在分布式机器学习、联合数据分析以及隐私保护推荐系统的构建中,我们常常面临一个核心矛盾:数据的所有权分散在多个互不信任的参与方手中,大家希望共同训练一个模型或进行一次计算&…...
告别硬编码!在UE Niagara中创建可复用的自定义模块库(以动态力场为例)
告别硬编码!在UE Niagara中创建可复用的自定义模块库(以动态力场为例)在虚幻引擎的视觉特效制作中,Niagara系统以其强大的粒子模拟能力成为特效师的核心工具。然而,随着项目复杂度提升,频繁复制粘贴相同逻辑…...
8051单片机16位SFR访问原理与安全实践
1. 16位特殊功能寄存器(SFR)的基础概念在8051单片机开发中,特殊功能寄存器(Special Function Register,简称SFR)是CPU与外围设备交互的关键接口。标准的8位SFR使用sfr关键字定义,而16位SFR则需要…...
告别虚拟机!在WSL2上搞定Mujoco物理引擎(保姆级避坑指南)
在WSL2中高效部署Mujoco物理引擎的完整实践指南当机器人学和强化学习开发者需要在Windows环境下进行高效开发时,WSL2已成为替代传统虚拟机和双系统方案的理想选择。然而,在WSL2中配置Mujoco物理引擎时,图形界面显示、依赖库安装和许可证配置等…...
为什么你的Gemini总生成错误JOIN?深度拆解语义理解断层、外键缺失与上下文截断三大黑洞
更多请点击: https://intelliparadigm.com 第一章:为什么你的Gemini总生成错误JOIN?深度拆解语义理解断层、外键缺失与上下文截断三大黑洞 当Gemini面对多表SQL生成任务时,频繁输出逻辑错误的JOIN语句——例如对无关联字段的表强…...
高校教务系统DES加密登录逆向实战:从抓包到Python自动化
1. 这不是“爬个登录”那么简单:为什么一个广东白云学院的登录接口值得花一整天逆向你可能刚看到标题就下意识划走——“又一个学校教务系统?不就是抓个包改个密码字段嘛”,我完全理解。去年帮朋友调试某高校选课脚本时,我也这么想…...
