TCP协议(建议收藏)

news2025/5/22 0:43:40

1. TCP特点

  1. 有连接:需要双方建立连接才能通信,在socket编程中服务端new ServerSocket(port)需要绑定端口,在客服端new Socket(serverIp, serverPort)与服务端建立连接
  2. 可靠传输:确认应答机制,超时重传机制
  3. 面向字节流:传输单位是字节
  4. 全双工:双向通信类似双行道

2. TCP的报文格式

image.png

  1. 源端口,目的端口:TCP的核心
  2. 32位序号,32位确认序号:确认应答机制中引入序号,防止后发先至的情况,32位序号针对请求数据进行编号,32位确认序号只针对ACK报文有效
  3. 选项:该部分可有可无,可以有以个选项也可以多个选项,选项可以是0个字节,最多40个字节
  4. 4位首部长度:描述TCP报头长度,单位是4字节,那就意味着报头长度最大是60字节(1111就是15*4=60)
  5. 保留位:现在没用,先占个位置
  6. 16位窗口大小:滑动窗口的大小,16位并不是说窗口最大是64kb,选项中有窗口大小的扩展因子,可以表示更大的窗口
  7. 16位校验和:校验发送和接收的时候数据是否一致

如果是第一次学可能会看懵掉,没关系,把下面内容看完再来看报文格式你就会很通透

3. 确认应答机制

image.png
当男生看到女生的回复后,就说明男生发的信息已经成功到达了,如果没有收到回复就可以认为上次发的数据丢失了。这就是确认应答机制,女生回复的“好的好的”就是应答报文ack。
image.png普通报文,ack为0;应答报文,ack为1

确认应答机制是TCP保证可靠性的最核心机制

当发送多条信息时可能出现下面情况:
image.png
此时女生后发的信息,男生先收到,让男生误以为女生答应了做他女朋友的请求,这是由于网络情况很复杂,很有可能“后发先至”。
解决方案就是对请求和返回的信息进行编号。
image.png
TCP是字节流协议,编号的时候,也是以字节为单位
image.png
image.png

4. 超时重传

当数据在传输过程中可能会发生丢包,因为网络环境很复杂,中间要经过很多路由器/交换机,某个交换机不但要传输我的数据还要传输别人的数据报,有很多很多数据报都要经过这个交换机,而交换机转发的能力是有上限的,很多数据报都经过该交换机,就会达到交换机的转发上限,就有可能导致有一部分数据报超时了。(类似于堵车)
当数据丢包的时候就要进行“超时重传”,丢包有两种情况一种是数据丢包,一种是应答报文丢了

  1. 数据丢包

image.png
当男生等了一段时间没收到女生的回应后,男生又在发了一次。这就是超时重传
第一次发生丢包时,发送方就会在达到超时时间的阈值之后,进行重传。如果重传的数据仍然没响应,就会继续重传,但是第二次超时的时间比第二次长,超时时间是逐渐变大的(假设一次丢包的概率10%,那两次都丢包的概率就是1%,说明网络情况比较差,后序在重传大概率也无法成功,不如降低传输频率,节省点主机开销)。如果重传几次后,仍然无法传输,就会尝试重置TCP连接(断开重连),如果还是连不上,就会释放连接。

  1. ack丢包

站在发送者的角度看,只知道没收到ACK,无法区分是发的数据丢了还是ACK丢了,因此发送者都会重传。如果是ACK丢包,发送者又重传就会导致接收方收到两份相同的数据,所以TCP会对相同的信息进行去重(根据序号进行去重)

5. 连接管理

TCP的连接是逻辑上虚拟连接,主机A和主机B建立连接,主机A的系统内核里有一个数据结构,包含了和他连接的是谁(IP,端口,使用的协议);主机B的内核的一个数据结构也记录了和他连接的谁(IP,端口,使用的协议)

5.1 三次握手

image.png
A发送syn尝试和B建立连接,主机B的内核立即返回ack接收对方的连接,内核同时也发送syn尝试和主机A建立连接,主机A返回ack接收对方的连接。建立连接的过程有四次数据交互过程,只不过主机B返回的ack和syn都是内核同时立即发送的,所以看起来就是三次的。

三次握手的意义

  1. 投石问路,检查当前网络情况是否通畅,这个期间并不传输任何业务数据
  2. 检查通信双方发送能力和接收能力是否正常,比如我约妹子打游戏

image.png
所以握手必须握三次才能够测试完整

  1. 协商一些重要的参数

例如TCP的序号并不是从1开始的,通常都是建立连接的时候协商一个数字,目的是保证两次连接的序号有差别,如果连接断开又快速重连,接收方就可以区分当前收到的数据是当前连接的还是上一个连接的。

两个重要的TCP状态

  1. LISTEN:服务器启动,绑定端口之后(new ServerSocket完成),服务器良好,可以让客服端连接(类似手机信号良好,可以让别人打电话给我)
  2. ESTABLISHED:连接建立好之后的稳定状态(类似于电话拨通,可以说话了)
5.2 四次挥手

通信双方,各自向对方申请断开连接,再各自给对方回应
image.png

四次挥手在某些情况下也会变成三次:TCP的捎带应答机制,会让ACK晚点发送,有可能和FIN(结束报文端)一起发送

两个重要的TCP状态
image.png

6. 滑动窗口

image.png
在没有引入滑动窗口之前是一问一答,主机A大量的时间都消耗在等待ACK上。因此提高效率的方法就是不等ACK,直接发送下一条数据。当然这里说的不等也不是完全不等而是每次批量发送一波数据,然后再等一波ACK,再发一波数据。这里不需要等待直接发送的数据的量,就称为“窗口大小”
image.png
批量发送4条数据,批量等待4条ACK,此时窗口大小就是4000字节。注意:主机A收到一条ACK就继续发一条数据,而不是等所有的ACK都到了,才统一发下一组。
image.png
发生一整波数据如果出现丢包/乱序时怎么办?

  1. 响应ACK丢了

image.png
这里的1001表示小于1001的数据都收到了,2001表示小于2001的数据都收到了,所以即使返回1001这个ACK丢了,下一次返回的2001就说明1-2000的数据已经收到了,包括了第一次的数据。这就类似于别人问你现在是高几呀?你说我已经大二了。
因此ACK丢包不需要任何处理

  1. 数据报丢了

image.png
在上面的过程中只是把丢的包进行了重传,没丢的包,没有重传,效率比较高,因此被称为“快速重传”(搭配滑动窗口机制的超时重传)

有了快速重传,超时重传还有意义吗?

在传输数据量很多,批量传输时自然是遵守快速重传的方式,如果传输的数据很少,此时仍然是按照超时重传的方式进行。在滑动窗口中如果是最后一个包丢了就是按照超时重传的方式。

窗口越大发送的速度越快,那窗口可以无限大吗?

发送的速度快了但是接收方的处理速度跟不上就会导致接收方丢弃一部分数据,而TCP需要保证可靠性的,TCP就要重传这些数据,这就导致了恶性循环。

7. 流量控制

在滑动窗口的基础上对发送速率做出限制的机制,根据接收方的接收能力,来反向影响发送方的发送速率。
接收方的接收速率如何衡量?

接收方使用接收缓冲区的剩余空间大小,来作为发送方发送速率(窗口大小)的参考数值

image.png
主机B收到的数据,就会先放到系统内核的接收缓冲区中,所谓缓冲区就是一个内存空间(字节数组)等待B这边的应用程序,通过Socket把数据从接收缓冲区中读取走。这就类似于生产者消费者模型A是生产者,往B的接收缓冲区生产数据,B的应用程序,从缓冲区中消费数据。
接收方B收到A的数据后,就会在ACK应答报文中,把当前接收缓冲区的剩余空间大小的值,反馈给发送方。
image.png

8. 拥塞控制

流量控制是通过接收方的接收速率,接收缓冲区剩余空间大小来衡量发送方的速率。在网络中不仅要考虑接收方还要考虑中间转发节点的情况。
如何衡量中间节点的情况?

把中间设备视为一个整体,通过实验来验证发送速度多少合适。开始的时候,发的慢一点,如果网络通畅就提高速度,提高到一定程度,发生丢包了,就再降低速度;速度降低后,发现又通畅了,就再提高速度。

image.png

9. 延迟应答

基于流量控制,引入的提高效率的机制,尽量让返回的接收缓冲区空间大一些,这样滑动窗口也就大一些,效率提高了。
image.png
image.png

10. 捎带应答

基于延时应答的基础上引入的
在4次挥手中说过,在某些情况下由于捎带应答机制可以变成3次
image.pngimage.png
TCP中只要把数据传输过去,对方收到之后,就会立即由内核返回一个ack报文,响应数据则是在应用程序中负责传输。由于这两操作是不同时机传输的,因此不能合并在一起,但是延时应答机制让这成为了可能。ACK原本是要立即返回的,但是由于延迟应答,稍等一会才返回,在某些情况下业务也正好在这个时候返回响应,此时就可以把这两个报文,合二为一了。

11. 面向字节流

面向字节流中存在一个典型问题“粘包问题”,举个例子
image.png
解决方案

要想解决粘包问题就要在应用层协议进行区分,只要定义应用层数据协议的时候,明确包和包之间的边界即可
1.通过分隔符,比如约定使用 ; 作为包结束的标记
2.指定包的长度,比如在数据包的开头位置声明长度

自定义应用层协议的几个典型实现,像xml,json,http这些都解决了粘包问题

12. TCP的异常处理

  1. 程序崩溃

进程异常退出,操作系统会回收进程资源,包括释放文件描述符表,这样的释放操作就相当于调用了对应的socket的close方法,执行close就会触发FIN结束报文,进一步进行四次挥手。

  1. 正常关机

关机的时候,系统会强制结束所有用户进程,和上述的进程崩溃类似。系统内核会进行文件描述符表的释放操作,进一步进行四次挥手

  1. 主机掉电
    1. 掉电的是接收方

此时发送方不知道对方挂了,继续发送数据,没有收到ACK,发送方就会触发超时重传,重传几次还没有应答就会尝试重置连接,失败后就会断开连接。

  1. 掉电的是发送方

接收方等了一段时间后,就会发送一个“心跳包”(心跳包是周期性触发的,只是一个简单的不携带任何业务数据的包)存在的意义就是确认一下对方是否存在,如果对方不返回心跳包就说明对方挂了,此时就放弃连接了。

  1. 网线断开

情况和主机掉电一样,只不过通信双方主机是正常的,通信双方各自按照上述的两种情况进行
13. 常见面试题
如何将UDP实现为可靠传输?
基于UDP的应用层实现确认应答机制,引入序列号,超时重传机制。

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

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

相关文章

Python开源项目PGDiff——人脸重建(Face Restoration),模糊清晰、划痕修复及黑白上色的实践

python ansconda 等的下载、安装等请参阅: Python开源项目CodeFormer——人脸重建(Face Restoration),模糊清晰、划痕修复及黑白上色的实践https://blog.csdn.net/beijinghorn/article/details/134334021 友情提示: …

vue 使用js new Map()优化多个if else 执行方法

前言 在实际开发中根据业务需求我们经常要判断情况,一个if 我们科技直接使用ES6就可以解决 经常会出现根据不同的条件执行不同的方法,这是就会有多个if else 看起不太美观也费劲 js new map ()就可以解决这个问题,它…

建行广东省江门市分行走进农村地区开展反假货币宣传

人民对美好生活的向往,涉及方方面面,小至“钱袋子”安全。建行广东省江门市分行落实当地监管部门部署,积极扛起维护国家金融安全的重要政治责任,深入农村地区开展反假货币宣传工作,助力构建农村反假货币工作长效机制。…

notes_质谱蛋白组学数据分析基础知识

目录 1. 蛋白组学方法学1.1 液相-质谱法1) 基本原理2) bottom-up策略的基本流程 1.2 PEA/Olink 2. 质谱数据分析2.1 原始数据格式2.2 分析过程1)鉴定2)定量3)预处理 2.3 下游分析 参考附录 1. 蛋白组学方法学 目前常见的蛋白组学方法学如下图…

【C/C++笔试练习】内联函数、函数重载、调用构造函数的次数、赋值运算符重载、静态成员函数、析构函数、模板定义、最近公共祖先、求最大连续bit数

文章目录 C/C笔试练习选择部分(1)内联函数(2)函数重载(3)调用构造函数的次数(4)赋值运算符重载(5)静态成员函数(6)调用构造函数的次数…

一句话讲明白buck和boost电源电路

大部分教程就是垃圾 虽然buck和boost结构上很像,但是是两个原理完全不一样的东西 BUCK(降压)电源 buck就是把方波,用LC滤波器后,变成正弦波 滤波:就是让电压缓慢增加,缓慢减少。&#xff08…

【SoC基础】DMA的工作原理

📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…

19.删除链表的倒数第N个结点(LeetCode)

想法一 先用tail指针找尾,计算出节点个数,再根据倒数第N个指定删除 想法二 根据进阶的要求,只能遍历一遍链表,那刚刚想法一就做不到 首先,我们要在一遍内找到倒数第N个节点,所以我们设置slow和fast两个指…

02. Python基础数据类型

1、前言 前面我们介绍了认识了Python以及Python的基础环境搭建,今天我们介绍下Python的一些基础语法。 2、Python基础 2.1、输入输出 2.1.1、输出 print() 用于输出指定的文字,括号中的为输出的字符串。print()也可以同时接收多个字符串,…

ESP32网络开发实例-将数据保存到InfluxDB时序数据库

将数据保存到InfluxDB时序数据库 文章目录 将数据保存到InfluxDB时序数据库1、InfluxDB介绍与安装3、软件准备4、硬件准备5、代码实现6、InfluxDB数据可视化在本文中,将介绍 InfluxDB 以及如何将其与 ESP32 开发板一起使用。 我们将向展示如何创建数据库桶并将 ESP32 数据发送…

Jupyter notebook 无法链接内核、运行代码

问题来源 今天想在 vscode 上使用 Jupyter notebook 跑 Python 代码,但无法使用,提示要升级内核。 Running cells with base requires the ipykernel package to be installed or requires an update. 其实这个问题存在好一段时间了,不过之前…

【教3妹学编程-算法题】Range 模块

3妹:哈哈哈哈哈哈哈哈 2哥 : 3妹看什么呢,笑的这么开森 3妹:2哥你快来看啊,成都欢乐谷的NPC模仿“唐僧”, 太搞笑了。 2哥 : 哦这个我也看到了,真的是唯妙唯肖,不能说像,只能说一模一…

webpack提升构建速度

目录 配置优化减少 resolve 的解析把 loader 应用的文件范围缩小减少 plugin 的消耗选择合适的 devtool 使用工具thread-loaderDLLPlugin 流程优化拆分构建步骤拆分项目代码 版本更新总结 前端项目随着时间推移和业务发展,页面可能会越来越多,或者功能和…

MYSQL索引+常见的锁

一)联合索引: 1)定义:是给一张表上面的多个列增加索引,也就是说给表上面的多个列增加索引,供快速查询使用,当两个列的组合是唯一值时,联合索引是个不错的选择 联合索引和单个索引对比来讲,联合索引的所有索引项都会出现…

左值右值笔记

左值右值 左值 左值是表示数据的表达式(如变量名或解引用的指针) 特点:可以获取地址,可以对他赋值。 位置:左值可以出现在赋值符号左边,也可以出现在赋值符号右边 右值 右值有:字面常量, 表达式返回值 …

用excel计算行列式的值

例如,我们要计算下面这个3*3矩阵的行列式的值: 127348569 鼠标点到其它空白的地方,用来存放计算后的结果: 插入-》函数: 选择MDETERM函数,这个就是计算行列式的函数: 点击“继续”&#xff1a…

函数极限求解方法归纳

1、连续函数直接代入值(加减不可以部分代入值) 例题1 配凑构造等价无穷小 等价无穷小 注意:不要在加减中部分使用等价无穷小,可以利用拆极限的方式求,拆出来的每一部分都要有极限,如果有一部分没有极限就是…

用excel计算矩阵的乘积

例如,我们要计算两个矩阵的乘积, 第一个矩阵是2*2的: 1234 第2个矩阵是2*3的: 5697810 在excel中鼠标点到其它空白的地方,用来存放矩阵相乘的结果: 选择插入-》函数: 选中MMULT,…

企业级信息化系统 ERP、OA、CRM、EAM、WMS、MES、PM

微服务架构,前端采用微应用架构,可做到不同服务使用不同数据库独立运行。全平台采用基于模型驱动的设计模式,并在前后端留有大量的代码植入入口,方便开发者对平台进行改造扩充。企业信息中心开发ERP、OA、CRM、EAM、WMS、MES、PM等…

PHP生成pdf格式准考证带照片完整示范

PDF效果图 PHP生成pdf格式准考证带照片完整示范以某省公务员考试下载的准考证模板为模板参考,故很有参考意义。 环境支持:linux PHP(5.5-7.3)环境,推荐宝塔环境。 基于fpdf.php插件开发,现有模板适合准考证生成并用于查询下载。 现有排版简单:替换data文…