文章目录
- TCP协议
- 确认应答
- 超时重传
- 连接管理
- 断开连接
TCP协议
TCP全称为"传输控制协议(Transmission Control Protocol").⼈如其名,要对数据的传输进⾏⼀个详细
的控制;
TCP协议段格式
• 源/目的端口号:表⽰数据是从哪个进程来,到哪个进程去;
• 32位序号/32位确认号:后⾯详细讲;
• 4位TCP报头⻓度:表⽰该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最⼤⻓度是15*4=60
• 6位标志位:
◦ URG:紧急指针是否有效
◦ ACK:确认号是否有效
◦ PSH:提⽰接收端应⽤程序⽴刻从TCP缓冲区把数据读⾛
◦ RST:对⽅要求重新建⽴连接;我们把携带RST标识的称为复位报⽂段
◦ SYN:请求建⽴连接;我们把携带SYN标识的称为同步报⽂段
◦ FIN:通知对⽅,本端要关闭了,我们称携带FIN标识的为结束报⽂段
• 保留(六位)reserved保留位:UDP协议长度受到2个字节的限制,想要进行扩展,发现扩展不了,一旦改变报头长度,就会使机器发送的UDP数据报和其他机器不兼容,TCP在设定报头的时候就提前准备了几个保留位,后续一旦需要扩展功能,使用保留位就可以实现,就可以避免TCP的扩展不兼容的问题
• 16位校验和:发送端填充,CRC校验.接收端校验不通过,则认为数据有问题.此处的检验和不光包含TCP⾸部,也包含TCP数据部分.
• 16位紧急指针:标识哪部分数据是紧急数据;
确认应答
网络传输过程中,经常会出现后发先至的情况,原因是:一个数据包从发送方到接收方传输过程中走的路径可能不一样,导致先发后至。
为了解决上述问题,引入了序号和确认序号,对数据进行编号,应答报文告诉发送方我应答是哪个数据
TCP将每个字节的数据都进⾏了编号.即为序列号
主机B收到1-1000这些字节数据之后反馈一个应答报文,应答报文中的确定序号的值就是1001,
1001的含义:
1.小于1001的数据都已经收到了
2.发送方接下来要给我发1001开始的数据了
TCP的确认应答是确保TCP可靠性的最核心机制
每⼀个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下⼀次你从哪⾥开始发.
超时重传
超时重传是确认应答的补充,如果一切顺利,通过应答报文就可以告诉发送方当前数据是不是成功收到,但是网络上可能存在丢包的情况,如果数据包丢了没有到达对方,对方自然也就没有ack报文,这种情况下就需要超时重传,当认为丢包之后,就会把刚才的数据包再传输一次,等待的过程有一个时间的阈值,就是“超时”。
• 主机A发送数据给B之后,可能因为⽹络拥堵等原因,数据⽆法到达主机B;
• 如果主机A在⼀个特定时间间隔内没有收到B发来的确认应答,就会进⾏重发;但是,主机A未收到B发来的确认应答,也可能是因为ACK丢失了;
TCP socket在内核中存在接收缓冲区(一块内存空间),发送方发来的数据是要先放到接收缓冲区的然后应用程序调用read/scanner.next才能读到数据,当数据再次接收到缓冲区时候,接收方首先会先判定是否存在,如果存在就会丢弃重复数据。
接收方如何判定这个数据是否是“重复数据” ? 核心判定依据是根据数据的序号
1.数据还在接收缓冲区里,没被read走,此时就拿着新接收的数据序号和缓冲区中的所有数据的序号核对
2.数据在接收缓冲区外,已经被应用程序read走了,此时新来的数据序号直接无法再接收缓冲区查到(注意:应用程序读取数据的时候是按照序号的先后顺序连续读取的,一定是先读序号小的数据后读序号大的数据
超时重传不是无限的重传,重传过程也是有一定策略的
1.重传次数是有上限的,重传到一定程度还没有ack应答就尝试重置连接,如果重置也失败了,就直接放弃连接
2.重传的超时时间阈值也不是固定不变的,随着重传的次数的增大,而增大(重传的频率越来越低)
连接管理
建立连接和断开连接是网络原理中高频的问题
在内核中是如何建立连接的?
TCP要经过 三次握手 建⽴连接,目的就是让通信双方都能保存对方的相关信息
上述的流程上讲,是有四次交互,但是实际过程中,其中的两次交互可以合二为一,最终形成了“三次握手”,所谓的建立连接过程,本质上就是通信双方各自给对方发起一个syn,各自给对方回应一个ack
注意:
- 客户端是主动的一方,第一次交互一定是客户端主动发起的
- 所谓的syn是一个特别的TCP数据报,没有载荷,不会携带应用层数据,六个标志位中的第五位,为1
三次握手的意义是什么?
- 三次握手,可以先针对通信路径,进行投石问路,初步的确定一下通信链路是否畅通
- 三次握手也是在验证通信双方发送能力和接受能力是否正常
断开连接
断开连接的本质目的就是为了把对端的信息从数据结构中删除掉/释放掉
四次挥手也是存在确认应答和超时重传
四次挥手,断开连接的第二次和第三次操作不能合二为一,因为在实际通信过程中,ack和第二个fin时间间隔比较长,此时就无法进行合并了,就要分成两次来传输
三次握手和四次挥手
相似之处:
都是通信双方各自给对方发起一个syn/fin,各自给对方返回ack
数据传输的顺序,syn/ack/syn/ack fin/ack/fin/ack
不同之处:
三次握手中间两次一定能合并,四次挥手则不一定
三次握手必须是客户端主动,四次挥手,客户端/服务器都可以主动
连接管理过程中涉及到的TCP状态转换
TCP服务器和客户端都有一定的数据结构来保存这个连接的信息
在这个数据结构中其中就有一个属性叫做“状态”
操作系统内核根据状态的不同,决定了当前应该干什么
LISTEN状态,表示服务器这边创建好了serverSocket了,并且绑定端口号完成
ESTABLISHED状态,表示客户端和服务器连接已经建立完毕(三次握手完成)
CLOST WAIT状态,表示收到对方的fin之后进入这个状态(谁被动断开连接谁进入CLOSE WAIT)
TIME WAIT状态,表示本端给对方发起FIN之后,对端也给本端发FIN,此时本端进入TIME WAIT(谁主动断开连接谁进入TIME WAIT)
TIME_WAIT 存在的意义,主要是防止,最后一个ACK丢包。客户端如果在这个环节,把TCP连接释放掉,此时意味着重传的FIN就无法被返回ACK了(保存对端信息的数据结构存在,才能给这个连接提供各种操作,才能返回ACK)
此时的TIME_WAIT等待也不是无休止的等待,最多等2MSL(MSL是一个系统内核的配置项,表示客户端到服务器之间,消耗的最长时间,这个时间一般是一个非常大的时间,常见的设置值是1min)