传输层——TCP协议

news2024/11/14 9:07:09

目录

一.TCP协议介绍

1.1简介

1.2TCP协议格式

32位序号/32位确认号 

 标志位

1.3tcp的发送和接收缓冲区

1.3.1介绍

1.3.2窗口大小

1.4超时重传

二.连接管理

2.1三次握手

2.2三次握手的状态变化

2.3为什么是三次握手?

 2.4套接字与三次握手关系

2.5四次挥手

2.6四次挥手的状态变化


一.TCP协议介绍

1.1简介

TCP全称为 " 传输控制协议 (Transmission Control Protocol"),其可靠性非常强,其应用非常广泛,例如:HTTPS,FTP、SSH。

1.2TCP协议格式

 各个字段的简单解释:

源/目的端口号表示数据是从哪个进程来 , 到哪个进程去。

32位序号/32位确认号 序号标定一个报文的编号;确认号标定 该确定号之前的报文全部收到 ,保证双向的全双工的确认应答机制,是TCP保证可靠性的重要字段。(后面详细介绍)

4位TCP报头长度(4位首部长度 ): 表示该 TCP头部有多少个32位bit(单位是4字节);此值是4bit位,则取值范围是0000~1111,即0~15,因为单位是4字节,所以TCP头部最大长度是15 * 4 = 60,而该报头标准长度有20,所以 4位首部长度 最少是 20 / 4字节 = 5=0101.即 4位首部长度 范围是0101~1111,20~60字节。(选项字段)则选项的大小的数据范围是0~40字节

16位校验和 :由发送端填充,采用CRC校验,用来验证数据在传输过程有没有问题。

16位窗口大小:应答本质就是要包含TCP报头,tcp报头可以有保存发送方接受能力的属性字段,叫做 16位窗口大小(后面详细解释)

16 位紧急指针 : 标识哪部分数据是紧急数据 ,标识紧急数据在报文中的偏移量,需要配合标志字段当中的URG字段统一使用。

TCP报头当中的6位标志位:

URG:紧急指针是否有效。
ACK:确认序号是否有效。
PSH:提示接收端应用程序立刻将TCP接收缓冲区当中的数据读走。
RST:表示要求对方重新建立连接。我们把携带RST标识的报文称为复位报文段。
SYN:表示请求与对方建立连接。我们把携带SYN标识的报文称为同步报文段。
FIN:通知对方,本端要关闭了。我们把携带FIN标识的报文称为结束报文段

TCP如何将报头与有效载荷进行分离,并向上交付

用先读取前20字节,读取其中的 4位首部长度, 4位首部长度*4 - 20 =  选项的大小 ,其余的就是有效载荷,再根据目的端口号,将数据上交给对应的(应用层)进程。

32位序号/32位确认号 

数据在传输的过程中,要确保数据可以安全,有序的到达。当一方收到消息后,还需要向对方发送响应,对方才能知道数据成功发送了。但严格意义上来说,互联网通信当中是不存在百分之百的可靠性的,因为双方通信时总有最新的一条消息得不到响应,但只需保证重要的数据能成功发送即可。对端如果没有收到对应的响应数据,会判定上一次发送的报文丢失了,此时对端可以将上一次发送的数据进行重传。

32位序号:

当双发进行通信,每次发送一次数据都要等待对方应答的话,那么效率是十分低的。TCP是允许一方连续发送多次数据的,但在连续发送多个报文时,由于各个报文在进行网络传输时选择的路径可能是不一样的,因此这些报文到达对端主机的先后顺序也就可能和发送报文的顺序是不同的,32位序号可以解决这些问题。

TCP将发送出去的每个字节数据都进行了编号,这个编号叫做序列号。

比如:发送的一方连续发送3次报文,那么这三个TCP报文当中的32位序号填的就是发送数据中首个字节的序列,此时接收端收到了这三个TCP报文后,就可以根据TCP报头当中的32位序列号对这三个报文进行顺序重排(该动作在传输层进行),重排后将其放到TCP的接收缓冲区当中,此时接收端这里报文的顺序就和发送端发送报文的顺序是一样的了

32位确认序号:

主要用来对另一方发送数据后,自己对其做出响应,表示自己已经收到了数据。

例如:当发送方连续发送了三个报文,该报文的大小都是1000字节的话,那么这三个报文所携带的32位序号可以认为是1,1001,2001,那么接受方发出的响应报文中的确认序号就是3001,表示下次向我发送数据时应该从序列号为3001的字节数据开始进行发送。若中间那个报文丢了,接受方发出的响应报文的确认序号就是1001,表示下次发送的数据要从1001开始,发送方就会从第二个报文开始重新传输。

 为什么要用两套序号机制?

TCP是全双工的,双方可以同时给对方发送消息。

  • 双方发出的报文当中,不仅需要填充32位序号来表明自己当前发送数据的序号。
  • 还需要填充32位确认序号,对对方上一次发送的数据进行确认,告诉对方下一次应该从哪一字节序号开始进行发送。

 标志位

SYN: 请求建立连接 ;,我们把携带SYN标识的称为同步报文段。

报文当中的SYN被设置为1,表明该报文是一个连接建立的请求报文。

只有在连接建立阶段,SYN才被设置,正常通信时SYN不会被设置。

ACK:

报文当中的ACK被设置为1,表明该报文可以对收到的报文进行确认。

多数情况下ACK都会被设置,因为都要进行应答。

FIN:

报文当中的FIN被设置为1,表明该报文是一个连接断开的请求报文。只有在断开连接阶段,FIN才被设置,正常通信时FIN不会被设置。

URG:

当URG标志位被设置为1时,需要通过TCP报头当中的16位紧急指针来找到紧急数据,紧急指针只有一个,它只能标识数据段中的一个位置,因此紧急数据只能发送一个字节。

PSH:

文当中的PSH被设置为1,是在告诉对方尽快将你的接收缓冲区当中的数据交付给上层。

补充:使用read/recv从缓冲区当中读取数据时,其实接收缓冲区和发送缓冲区都有一个水位线的概念,当数据接近这个水平线才会进行读取,减少不必要的消耗。

RST:

报文当中的RST被设置为1,表示需要让对方重新建立连接。
在通信双方在连接未建立好的情况下,一方向另一方发数据,此时另一方发送的响应报文当中的RST标志位就会被置1,表示要求对方重新建立连接。
在双方建立好连接进行正常通信时,如果通信中途发现之前建立好的连接出现了异常也会要求重新建立连接。

1.3tcp的发送和接收缓冲区

1.3.1介绍

TCP是具有发送与接受缓冲区的,我们用write/send函数把数据拷贝到内核缓冲区后,tcp会在合适时候进行发送。我们只是将数据拷贝到对应的缓冲区内。

内核缓冲区的数据什么时候发,发多少,出错了怎么办,要不要添加提高效率的策略——都是由OS内的TCP自主决定的,所以TCP叫做传输控制协议!

意义:

  • 数据在传输过程中可能出现错误,那么就要进行重传,因此TCP必须提供一个发送缓冲区来暂时保存发送出去的数据,以免需要进行数据重传。只有当发出去的数据被对端可靠的收到后,发送缓冲区中的这部分数据才可以被覆盖掉。
  • 接收端处理数据的速度是有限的,为了保证没来得及处理的数据不会被迫丢弃,因此TCP必须提供一个接收缓冲区来暂时保存未被处理的数据

1.3.2窗口大小

在数据进行传输的过程中,可能一方发送的数据过大,导致另一方不能接受那么多的数据。

16位窗口:16位窗口大小当中填的是自身接收缓冲区中剩余空间的大小,也就是当前主机接收数据的能力。接收端在对发送端发来的数据进行响应时,就可以通过16位窗口大小告知发送端自己当前接收缓冲区剩余空间的大小,此时发送端就可以根据这个窗口大小字段来调整自己发送数据的速度。

双方的发送缓冲区是在得知对方接收缓冲区接收能力的条件下进行通信的,根据对方每次应答中不断更新的窗口大小定期向对方发送合适的数据大小,这种策略就叫做流量控制策略。流量控制策略也是双向的。

在三次握手期间不仅仅是建立链接,还有就是交换信息 ,其中信息就包含了向对端告知自己的接收能力。

1.4超时重传

概念:当一方发送数据后,在一定时间内没有收到对方的响应,就要重新对该数据进行发送。

注意:TCP保证双方通信的可靠性,一部分是通过TCP的协议报头体现出来的,还有一部分是通过实现TCP的代码逻辑体现出来的。

这里可能是发送的数据丢了或者是对方发出的响应丢了,都要进行重传。

 补充:

若是因为没有收到对方的响应而进行重传,那么接受方会收到两个相同的报文,但可以通过32位序列号来进行去重。

由于缓冲区的存在,当数据发送后,不会立即将缓冲区的数据清空,而是当收到响应后再清空。

超时的时间如何确定? 

最理想的情况下, 找到一个最小的时间 , 保证 " 确认应答一定能在这个时间内返回 ",  但是这个时间的长短, 随着网络环境的不同 , 是有差异的 。TCP 为了保证无论在任何环境下都能比较高性能的通信 , 因此会动态计算这个最大超时时间 .
  Linux中 (BSD Unix 和 Windows 也是如此 ), 超时以 500ms 为一个单位进行控制 , 每次判定超时重发的超时 时间都是500ms 的整数倍 .
 如果重发一次之后, 仍然得不到应答 , 等待 2*500ms 后再进行重传 .
如果仍然得不到应答, 等待 4*500ms 进行重传 . 依次类推 , 以指数形式递增 。

当重传超过一定次数,TCP 认为网络或者对端主机出现异常, 强制关闭连接。

二.连接管理

TCP是面向连接的,如何去理解?

我们在进行TCP通信之前需要先建立连接,就是因为TCP的各种可靠性保证都是基于连接的,要保证传输数据的可靠性的前提就是先建立好连接

建立连接:实际就是在操作系统中用该结构体定义一个结构体变量,然后填充连接的各种属性字段,最后将其插入到管理连接的数据结构当中即可。

断开连接:实际就是将某个连接从管理连接的数据结构当中删除,释放该连接曾经占用的各种资源。

2.1三次握手

二者在进行通信之前,要先建立连接,而建立连接的这个过程,叫做三次握手。

 具体解释:

第一次握手:客户端向服务器发送报文当中的SYN位被设置为1,表示请求与服务器建立连接。
第二次握手:服务器在收到客户端发来的连接请求报文后,便向向客户端发起连接建立请求并且对客户端发来的连接请求进行响应,此时服务器向客户端发送的报文当中的SYN位和ACK位都被设置为1。
第三次握手:客户端收到服务器发来的报文后,得知服务器收到了自己发送的连接建立请求,并请求和自己建立连接,最后客户端再向服务器发来的报文进行响应。

2.2三次握手的状态变化

刚开始时,客户端与服务器都处于CLOSED状态。后服务器转化为LISTEN状态,客户端就可以向服务器发起三次握手了,当客户端发起第一次握手后,客户端状态变为SYN_SENT状态。

处于LISTEN状态的服务器收到客户端的连接请求后,会将该连接放入内核等待队列中,并向客户端发起第二次握手,此时服务器的状态变为SYN_RCVD。处于SYN_RCVD状态的客户端收到服务器的第二次握手请求后,客户端便建立好连接了,变为ESTABLISHED状态。

而服务器收到客户端发来的最后一次握手后,连接也建立成功,此时服务器的状态也变成ESTABLISHED。

2.3为什么是三次握手?

首先要明白的是,在建立连接的过程中,收到数据的一方都要向另一方做出响应,这也就意味着可能在某次握手的过程中出现丢包等情况,导致一方未收到数据或者响应等。在三次握手的过程中,最后一次握手的可靠性是不能保证的。

理由:

三次握手是验证双方通信信道的最小次数

在客户端一方来看,当它收到服务器发来第二次握手时(SYN+ACK),说明自己发出的第一次握手被对方可靠的收到了,并且证明自己发送,服务器可以接受。同时当自己收到服务器发来的第二次握手时,也就证明服务器能发以及自己能收,此时就证明自己和服务器都是能发能收的。


在服务器看来,当它收到客户端发来第一次握手时,证明客户端能发以及自己能收,而当它收到客户端发来的第三次握手时,说明自己发出的第二次握手被对方可靠的收到了,也就证明自己能发以及客户端能收,此时就证明自己和客户端都是能发能收的。

 三次奇数次握手可转移风险

只有当服务器收到客户端发来的第三次握手后,服务器才知道双方通信信道是连通的,此时在服务器端才会建立对应的连接。若第三次握手服务器未收到,那么服务器端就不会建立对应的连接,而在客户端就需要短暂的维护一个异常的连接。而维护连接是需要时间成本和空间成本,这样可避免影响到服务器的资源。

 2.4套接字与三次握手关系

在服务器处于LISTENED状态时,客户端就可以向服务器发送连接请求了,这里用到的是connect函数。

 注意:connect函数不参与底层的三次握手,connect函数的作用只是发起三次握手。当connect函数返回时,要么是底层已经成功完成了三次握手连接建立成功,要么是底层三次握手失败。

如果服务器端与客户端成功完成了三次握手,此时在服务器端就会建立一个连接,但这个连接在内核的等待队列当中,此时服务器端只需要通过调用accept函数将这个建立好的连接获取上来。

 后面二者就可以通过对应的套接字,通过read与write函数进行通信了。

2.5四次挥手

当二者通信结束后,要断开这种连接,这个过程叫做四次挥手。

 具体解释:

第一次挥手:客户端向服务器发送报文当中的FIN位设置为1,表示请求与服务器断开连接。
第二次挥手:服务器收到客户端发来的断开连接请求后对其进行响应。
第三次挥手:服务器收到客户端断开连接的请求,且已经没有数据需要发送给客户端的时候,服务器就会向客户端发起断开连接请求。
第四次挥手:客户端收到服务器发来的断开连接请求后对其进行响应。

2.6四次挥手的状态变化

二者建立好连接请求时,它们的状态都是ESTABLISHED

客户端为了与服务器断开连接,主动向服务器发起连接断开请求(FIN),此时客户端的状态变为FIN_WAIT_1
服务器收到客户端发来的连接断开请求后对其进行响应,此时服务器的状态变为CLOSE_WAIT
当服务器没有数据需要发送给客户端的时,那么此时服务器会向客户端发起断开连接请求,等待最后一个ACK到来,此时服务器的状态变为LASE_ACK
客户端收到服务器发来的第三次挥手后,会向服务器发送最后一个响应报文,此时客户端进入TIME_WAIT状态。
当服务器收到客户端发来的最后一个响应报文时,服务器会关闭连接,转变变为CLOSED状态。
而客户端则会等待一个2MSL(Maximum Segment Lifetime,报文最大生存时间)才会进入CLOSED状态。

套接字与四次挥手关系:

这里也就是双方完成通信后,要调用close函数。一个close函数对应两次挥手。

CLOSE_WAIT:当客户端调用close函数,而服务端没有调用该函数的话,此时服务器就会进入CLOSE_WAIT状态,而客户端则会进入到FIN_WAIT_2状态。此时服务器依旧要花资源去维护这段连接,这其实也是一种内存泄漏的问题。

TIME_WAIT:说下这种状态的必要性,二者再断开连接的时候,发送的数据都可能出现丢包,对方数据未被收到等情况。但可以进行超时重传,但客户端最后发送ACK应答时,就马上进入CLOSED状态的话,若客户端未收到这条ACK应答,这对服务器便不好,可能会长间处于LAST_ACK状态。若客户端处于TIME_WAIT状态,服务器未收到最后一条ACK应答时,客户端还可以能收到服务器重发的报文然后进行响应。所以这个状态可以较大概率保证最后一个ACK被服务器收到。

这个时间不能太长也不能太短,

CP协议规定,主动关闭连接的一方在四次挥手后要处于TIME_WAIT状态,等待两个MSL(Maximum Segment Lifetime,报文最大生存时间)的时间才能进入CLOSED状态。

MSL在RFC1122中规定为两分钟,但是各个操作系统的实现不同,比如在Centos7上默认配置的值是60s。我们可以通过cat /proc/sys/net/ipv4/tcp_fin_timeout命令来查看MSL的值

 

TIME_WAIT的等待时长设置为两个MSL的原因:

  • MSL是TCP报文的最大生存时间,因此TIME_WAIT状态持续存在2MSL的话,就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失。
  • 同时也是在理论上保证最后一个报文可靠到达的时间。

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

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

相关文章

C++11:类的新功能和可变参数模板

文章目录1. 新增默认成员函数1.1 功能1.2 示例2. 类成员变量初始化3. 新关键字3.1 关键字default3.2 关键字delete补充3.3 关键字final和override4. 可变参数模板4.1 介绍4.2 定义方式4.3 展开参数包递归展开参数包优化初始化列表展开参数包逗号表达式展开参数包补充5. emplace…

华为OD机试用Python实现 -【报数游戏】2023Q1 A卷

华为OD机试题 本篇题目:报数游戏题目输入输出示例 1输入输出示例 2输入输出Code代码编写思路最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解

会声会影2023旗舰版新功能介绍,Corel VideoStudio Ultimate2023以及电脑系统配置要求

会声会影2023中文旗舰版功能非常强大的视频编辑软件,非常专业的使用效果,会声会影2023中文版可以针对剪辑电影进行使用,非常强大的色彩校正方式,无论什么光线下进行拍摄,都可以通过后期进行调整,并且里面超…

Python SEO采集海量文本标题,用倒排索引找出“类似的标题“代码实现

Python SEO采集海量文本标题,用倒排索引找出“类似的标题“代码实现 作者:虚坏叔叔 博客:https://xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 一、说明 假设这个是采集到的海量文本标题: 现在要判断找到的这个标题 title = "拜登称特朗普拒绝承认选举…

C语言实验小项目实例源码大全订票信息管理系统贪吃蛇图书商品管理网络通信等

wx供重浩:创享日记 对话框发送:c项目 获取完整源码源文件视频讲解环境资源包文档说明等 包括火车订票系统、学生个人消费管理系统、超级万年历、学生信息管理系统、网络通信编程、商品管理系统、通讯录管理系统、企业员工管理系统、贪吃蛇游戏、图书管理…

再见 ETHDenver 2023

我们来一起回顾Web3中规模最大,持续时间最长的以太坊史诗级建造周我们正在庆祝#YearoftheSpork,并借助 Web3 中最大的以太坊社区活动之一拉开了黑客马拉松赛季的序幕。ETH Denver 旨在围绕一个共同的目标聚集了志同道合的人,我们非常高兴今年…

开学新装备 - 学生党是否该入手 MacBook

学生党是否该入手 macbook 这个问题,相信许多人在许多社区都有看到过类似讨论。只不过,许多讨论都掺杂了信仰、智商税、不懂、不熟悉未来需求等各种因素,导致内容空洞价值不大。这篇文章,抛开了所有非理性因素,详细的告…

创建第一个QT程序

系列文章目录 QT学习与实战 创建第一个QT程序系列文章目录一、创建第一个QT程序1.1Location(项目简介和位置)1.2Kits(构建套件)1.3Details(类的信息)1.4汇总二、常用操作2.1显示文件分类2.2代码分栏三、代码分析四、总结一、创建第一个QT程序 1.1Location(项目简介和位置) 创…

2.进程和线程

1.进程1.1 终止正常退出(自愿)出错退出(自愿)严重错误(非自愿)被其他进程杀死(非自愿)1.2 状态就绪态:可运行,但因为其他进程正在运行而暂时停止阻塞态:除非某种外部事件发生,否则进程不能运行1.3 实现一个进程在执行过程中可能被…

淘宝十年资深架构师吐血总结淘宝的数据库架构设计和采用的技术手段。

淘宝十年资深架构师吐血总结淘宝的数据库架构设计和采用的技术手段。 文章目录淘宝十年资深架构师吐血总结淘宝的数据库架构设计和采用的技术手段。本文导读1.分库分表2.数据冗余3.异步复制4.读写分离总结本文导读 淘宝的数据库架构设计采用了分布式数据库技术,通过…

MES系统消除制造型企业的九大浪费!

在生产制造型企业,正确地减少不必要的浪费才是降低生产成本、提升企业利润的关键! 许多制造型企业的管理者,尤其是中层管理者没有认识到在生产管理过程中哪些行为是在真正提升企业效益、哪些行为是给企业制造浪费。 对于传统的浪费有过量生…

基于Hyperledger Fabric的学位学历认证管理系统

基于Hyperledger Fabric的学位学历认证管理系统 项目源码:https://github.com/Pistachiout/Academic-Degree-BlockChain 一、选题背景 学历造假、认证造假等是一个全球日益普遍的现象,不仅对社会产生了巨大的负面影响,同时也极大增加了企业…

极限的准则

目录 定理: 极限运算法则: 极限存在之间的计算: 例题: 定理: 定理: 定理1和定理2的证明方式类似,我们对定理2进行证明。 我们举一个例子: 这道题目的结果是0,但是计算…

excel 数据查询,几个模式化公式请收好

1、一对多查询 所谓一对多,就是符合某个指定条件的有多个结果,要把这些结果都提取出来。 如下图所示,希望根据F2单元格中指定的部门,提取出左侧列表中“生产部”的所有人员姓名。 Excel 2019及以下版本:在H2单元格输…

【教学典型案例】17.环境混用带来的影响

目录一:背景介绍二:思路&方案思路方案1、分权2、定期对比环境混乱的危害三:过程1、排查nginx请求转发是否正常2、找到开发环境项目的服务器,查看服务器配置的nginx3、从fastdfs服务器上找到安装存储的位置4、排查结果四&#…

Java代码优化|提高代码质量的一些小技巧

1.需要 Map 的主键和取值时,应该迭代 entrySet()当循环中只需要 Map 的主键时,迭代 keySet() 是正确的。但是,当需要主键和取值时,迭代 entrySet() 才是更高效的做法,比先迭代 keySet() 后再去 get 取值性能更佳。正例…

python进程间通信

进程间通信表示进程之间的数据交换。 为了开发并行应用程序,需要在进程间交换数据。 下图显示了多个子过程之间同步的各种通信机制 - 各种通信机制 队列 队列可以用于多进程程序。 多处理模块的Queue类与Queue.Queue类相似。 因此,可以使用相同的API…

【带你搞定第二、三、四层交换机】

​ 01 第二层交换机 OSI参考模型的第二层叫做数据链路层,第二层交换机通过链路层中的MAC地址实现不同端口间的数据交换。 第二层交换机主要功能,就包括物理编址、错误校验、帧序列以及数据流控制。 因为这是最基本的交换技术产品,目前桌面…

07-PL/SQL基础(if语句,case语句,循环语句)

本章主要内容: 1.PL/SQL的基本构成:declare,begin,exception,end; 2.结构控制语句:IF语句,CASE语句 3.循环结构:loop循环,for loop循环,while loop循环 PL/SQL的基本构成 特点 PL/SQL语言是SQL语言的扩展&#xff…

JS学习笔记day03

今日内容 零、 复习昨日 CSS 美化,复用,样式文件和表现文件分离便于维护 选择器 {属性:值;…} 引入css 内联文件内部使用style标签外部文件 <link href"路径" rel"stylesheet" type"text/css"> 选择器 基本 idclass标签名 属性 标签名…