为什么TCP是面向字节流协议

news2024/12/24 1:05:40

大家好,我是三叔,很高兴这期又和大家见面了,一个奋斗在互联网的打工人。

笔者在TCP 机制一文中有说到 TCP 是面向字节流的,这篇博客给大家介绍一下:为什么 TCP 是面向字节流协议的。

首先说一下 UDP ,是一个面向报文的协议,当用户消息通过 UDP 协议传输时,操作系统不会对消息进行拆分,在组装好 UDP 头部后就交给网络层来处理,所以发出去的 UDP 报文中的数据部分就是完整的用户消息,也就是每个 UDP 报文就是一个用户消息的边界,这样接收方在接收到 UDP 报文后,读一个 UDP 报文就能读取到完整的用户消息。

如果收到了两个 UDP 报文,那么 UDP 是如何将这些消息进行区分的?

如图所示:UDP 底层维护了一个队列,通过对队列进行消费
在这里插入图片描述

那么,为什么 TCP 是面向字节流

当用户消息通过 TCP 协议传输时,消息可能会被操作系统分组成多个的 TCP 报文,也就是一个完整的用户消息被拆分成多个 TCP 报文进行传输。这时,接收方的程序如果不知道发送方发送的消息的长度,也就是不知道消息的边界时,是无法读出一个有效的用户消息的,因为用户消息被拆分成多个 TCP 报文后,并不能像 UDP 那样,一个 UDP 报文就能代表一个完整的用户消息。

例如:发送方准备发送 hello 和 world 这两个消息,在发送端,当我们调用 send 函数完成数据 “发送” 以后,数据并没有被真正从网络上发送出去,只是从应用程序拷贝到了操作系统内核协议栈中。至于什么时候真正被发送,取决于发送窗口、拥塞窗口以及当前发送缓冲区的大小等条件。也就是说,我们不能认为每次 send 调用发送的数据,都会作为一个整体完整地消息被发送出去。所以发送 hello + world 信息,如果没有分界,会出现 hel + loworld,又或者 hell + oword等。

我们不知道 hello 和 world 这两个用户消息是如何进行 TCP 分组传输的。
因此,我们不能认为一个用户消息对应一个 TCP 报文,正因为这样,所以 TCP 是面向字节流的协议。

当两个消息的某个部分内容被分到同一个 TCP 报文时,就是我们常说的 TCP 粘包问题,这时接收方不知道消息的边界的话,是无法读出有效的消息。

要解决这个问题,要交给应用程序。

如何解决粘包

一般有三种方式分包的方式:

  1. 固定长度的消息:
    比如规定一个消息的长度是 64 个字节,当接收方接满 64 个字节,就认为这个内容是一个完整且有效的消息。但是这种方式灵活性不高,实际中很少用

  2. 特殊字符作为边界:
    如果报文中就有特殊字符,那么系统很有可能将消息中的特殊字符当成分界点,刚好消息内容里有这个特殊字符,我们要对这个字符转义,避免被接收方当作消息的边界点而解析到无效的数据。
    在这里插入图片描述

  3. 自定义消息结构:
    可以自定义一个消息结构,由包头和数据组成,其中包头包是固定大小的,而且包头里有一个字段来说明紧随其后的数据有多大。当接收方接收到包头的大小(比如 4 个字节)后,就解析包头的内容,于是就可以知道数据的长度,然后接下来就继续读取数据,直到读满数据的长度,就可以组装成一个完整到用户消息来处理了。

总结

所以 TCP 是面向字节流的协议,在消息体传输的过程中,是分段进行的,而 UDP 则是面向报文的传输协议,一次发送一个报文,用一个队列来维护。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/745951.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

prompt:有需求就有价值,prompt案例

prompt:有需求就有价值 此文章来自于小七姐 首先来看需求: 客户需要生成1000条俏皮灵动,趣味盎然,比喻精妙的和美食有关的短句子,要求文风优美,句子让人充满食欲。 客户使用这些句子的场景比较奇妙&…

eval() trim() dispaly:contents等属性的理解

1.eval(除去前后的双引号) 2.字符串.trim() 除去前后的空格 3.display:contents(提升到父级元素的子集元素)

How to Make Your Writing Stand Out From AI 如何让你的写作从人工智能中脱颖而出

Thanks to amazing tools such as ChatGPT, there is now a flood of well-written, functional, and useful writing to compete with if you’re a human writer. This means your writing needs to differentiate itself from this new breed of content. Here’s how to do…

OSError [Errno 22] Invalid argument(已解决)

最近跑别人的项目遇到一个这样的问题 OSError: [Errno 22] Invalid argument xxxxxxxxxxxxxxxxxx一开始以为是没有用管理员的权限运行,导致创建不了日志文件 后来发现是和windows的命名规则冲突了(以下来源官网地址) 命名约定 以下基本规…

希尔排序法解析

希尔排序法解析 什么是希尔排序法 希尔排序法(Shell Sort),也称为缩小增量排序,是一种改进的插入排序算法。它通过将待排序的元素按照一定的间隔分组,对每个分组进行插入排序,逐渐减小间隔直至为1&#x…

单个电源模块不带电感的直流压降仿真

单个电源模块不带电感的直流压降仿真 前面讲过POWER DC如何对单个电源模块带电感的直流压降仿真,下面介绍如何对单个电源模块不带电感的直流压降仿真,以下图为例

启动优化中的一些黑科技,了解一下~

1前言 启动速度优化是 android 开发中的常见需求,除了一些常规的手段之外,也有一些黑科技手段,我们来看一下这些黑科技手段是否有效,以及如何实现 本文主要是对Android 性能优化小册相关内容的学习实践,加入了自己的…

腾讯云服务器CVM实例族区别如何选择?

腾讯云服务器CVM有多种实例族,如标准型S6、标准型S5、SA3实例、高IO型、内存、计算型及GPU型实例等,如何选择云服务器CVM实例规格呢?腾讯云服务器网建议根据实际使用场景选择云服务器CVM规格,例如Web网站应用可以选择标准型S5或S6…

linux 读取文件,并输出含空格的每一行

[devusercdp-node12 ~]$ cat test.sh 1234 aaaa 2345 bbbb 3456 cccc 需求 输出三行 分别是 aaaa bbbb cccc 咋一看很简单,实则里面有很多小问题。 rescat test.sh 这个时候思考下 echo $res和 echo "$res"有啥区别 快速的写出for循环 结果 for i in …

Web3 开发指南:使用 NFTScan NFT API 构建一个 NFT 链上追踪器

对于大多数 Web3 团队来说,构建一个完整的链上 NFT 数据追踪系统是一项具有挑战性的任务,构建一个 NFT 链上追踪器更是如此。涉及到处理区块链上的智能合约和交易数据,并将其与外部数据源进行整合和分析工作量是十分巨大的: 区块链…

图像分类——ResNet

目录 残差块ResNet模型手写数字识别 残差块 左图残差块实现如下 import tensorflow as tf from tensorflow.keras import layers,activations#残差块 class Residul(tf.keras.Model):def __init__(self,num_channels,use_1x1convFalse,strides1):super(Residul,self).__init_…

2023年最值得关注的APP开发工具

随着越来越多的开发人员转向移动应用程序开发,行业和企业都在寻找最好的工具来帮助他们。随着市场的变化,客户越来越注重质量和开发效率。 无论您是要创建一个全新的 APP,还是要寻找一种可快速部署的工具来满足您的需求,这篇文章…

RT1176 将代码放到RAM上运行

为了实现IAP固件升级,需要擦写Flash。如果代码在Nor Flash上运行,同时擦写该Flash,代码就会乱了无法正常执行。所以我们要先将代码放到RAM上运行。 但又不能像官方SDK Demo那样将代码直接烧录到RAM上或SDRAM上,否则掉电后代码丢失…

CSS样式表的学习

CSS样式,在前面学习HTML的结构时,也讲过一点。大概知道CSS样式如何使用。现在,系统的讲述一下CSS的用法,以及关于CSS样式的一些结构。 参考文章:CSS 背景图像重复 (w3schools.com) 一、CSS介绍 CSS 代表 层叠样式表…

蚂蚁集团开源可信隐私计算框架「隐语」:开放、通用

7 月 4 日,蚂蚁集团宣布面向全球开发者正式开源可信隐私计算框架 “隐语”。 隐语是蚂蚁集团历时 6 年自主研发,以安全、开放为核心设计理念打造的可信隐私计算技术框架,涵盖了当前几乎所有主流隐私计算技术。 据介绍,隐语内置 MPC、TEE、同态等多种密态计算虚拟设备,提…

【Java实现AES加解密】

Java实现AES加解密 这篇文章主要介绍了使用Java实现加密之AES加解密,AES为最常见的对称加密算法,对称加密算法也就是加密和解密用相同的密钥,需要的朋友可以参考下在Vue中,Vue加密:Java解密: 这篇文章主要介绍了使用Java实现加密之AES加解密,…

Linux开发工具【vim】

Linux开发工具之【vim】 文章目录: Linux开发工具之【vim】1. Linux软件包管理器yum1.1 查看软件1.2. 下载软件1.3 卸载软件 2. vim编辑器的使用2.1 vim常用模式2.2 vim基本操作2.3 vim命令模式命令集2.3.1 移动光标2.3.2 删除文字2.3.3 复制文本内容2.3.4 替换文本…

设计模式——组合模式

组合模式 定义 组合模式(Composite Pattern)又称为合成模式、部分-整体模式(Part-Whole),主要用来描述部分与整体的关系。 定义:将对象组合成树形结构以表示“部分-整体”的层次结构,使用户对…

【C#】并行编程实战:同步原语(2)

在第4章中讨论了并行编程的潜在问题,其中之一就是同步开销。当将工作分解为多个工作项并由任务处理时,就需要同步每个线程的结果。线程局部存储和分区局部存储,某种程度上可以解决同步问题。但是,当数据共享时,就需要用…

电商项目“商品分类浏览”如何测试?附详细思维导图

电商项目无论是工作中,还是面试中,都是一个高频出现的词。面试官非常热衷提问关于电商项目的问题。例如商品分类怎么测试?购物车怎么测试?订单怎么测试?优惠券怎么测试?支付怎么测试?等等 今天…