TCP协议详解
介绍TCP协议之前,先区分一下TCP协议,和TCP/IP体系结构。TCP协议是TCP/IP协议体系中运输层的协议之一,提供可靠的运输层服务,具有面向连接,面向字节流,提供可靠交付,据用流量控制和拥塞控制等特点。
先简单介绍一下TCP/IP体系结构, 以便于清晰一下自己所在协议栈的位置。
OSI七层太过复杂,且没有在开始的时候快速占领市场。当时一直到现在使用的都是TCP/IP体系结构,但是为了更好的阐述基本原理,还是按照五层体系结构来划分说明。
TCP/IP协议族
传输控制协议TCP
概述
协议特点:
- 面向连接的协议:建立连接、关闭连接
- 点对点:连接只能有2个端点
- 可靠交付:无差错、不丢失、不重传、按顺序交付给应用层
- 全双工:通信双方在任何时候都能够发送数据
- 面向字节流:每个字节都有序号,比如说累积确认,确认号就是下一个字节编号
报文剖析
下面对部分首部字段详细说明:
- 序号:是报文段数据部分的字节的序号。在首部中占4个字节,2的32次幂个序号。超过后,回到0。之所以说TCP面向字节流,是因为每个字节都有一个序号。如序号是301,数据共100字节,那么最后一个字节的序号是400。所以下一个报文段的序号从401开始。
- 确认号:是作为接受方的一端在收到tcp报文后,期望下一次收到的字节的序号,继续上文序号的例子,收到301,数据长度100,那么再ack这个报文的时候,确认号应该是401(301+100)
这里有个重要的概念——累积确认,就是说,如果:
确认号=N,表明,到序号N-1为止的所有数据都已经正确收到!
数据偏移:数据部分距离首部有多远(因为tcp报文段中包含可变长度的选项,不能根据位数定位数据部分)
控制位URG
控制位ACK:ACK=1时候,确认号字段才有意义,说明该报文包含确认
控制位PSH:为1时,表明接收方收到报文后要尽快交付给应用层
控制位RST:Reset复位,连接出现严重差错,必须释放连接然后再重建连接
控制位SYN:建立连接的时候使用,用来同步报文起始序号
控制位FIN:finish,释放连接的时候使用
窗口:占2字节,表明作为接收方,我还有多少字节的缓冲空间来接受新的字节,数据的单位是字节,该值作为发送方设置其发送窗口大小的依据
可靠传输
滑动窗口动态视频-Normal
滑动窗口动态视频-Error
右边的图反转一下更容易理解。
流量控制
接收方来不及接收,会造成数据丢失。所谓流量控制就是让发送发不要发送的太快。
主要利用滑动窗口来控制。
这里有个知识点,就是当接收窗口为0之后,如何打破死锁局面。打破的方法就是发送端发送零窗口探测报文(似乎也是keep alive报文),接收方在确认这个报文的时候,将新的窗口值带上,如果不是0,死锁就打破了。
拥塞控制
- 慢开始
- 拥塞避免
- 快速重传
- 快速恢复
连接管理
三次握手建立连接,四次交互关闭连接。连接的状态变化。
建立连接
经过下图的三次握手之后,连接被成功建立。
- 客户机A请求服务器B打开连接,进入SYN-SENT状态
- 服务器B响应“打开连接的请求”,进入SYN-RCVD状态
- 客户机A收到SYN-SEND的ack, 进入ESTABLISHED状态,并再一次确认B的响应,这次可以携带数据也可以不携带数据,SYN=1, ACK=1, seq=x+1, ack=y+1, 机器B在收到此确认后,进入ESTABLISHED状态
这期间server或会设定MSS等参数
释放连接
- 机器A请求关闭连接,发送终止信号,进入FIN-WAIT阶段一(终止等待1),等待机器B的确认
- B收到A的终止信号,随即发送确认,并通知上层进程,进入CLOSE-WAIT,关闭等待状态;这时候从A到B这个方向的连接释放了,TCP连接的状态为办关闭状态。A已经没有数据要发送了,但是B可能还有数据要发送,并可以继续发送;
- 当A收到B对终止信号的确认,A进入终止等待2,等待B最终的确认;当B没有数据发送的时候,B会再次确认A的终止信号(意在关闭B到A方向上的连接),B进入LAST-ACK状态
- A收到B对终止信号的第二次确认后,A发送对确认的确认,进入TIME-WAIT状态;当B收到确认后,关闭连接回收资源;当2MSL之后,A也关闭连接,释放资源
MSL: max segment lifetime, 最大报文寿命
MSS: max segment size 最大报文长度
TIME-WAIT阶段等待2MSL的作用:
1. 如果B没有收到最后的ACK, B会重传FIN=1, 当A收到这个重传的FIN=1, 最大时间刚好是2MSL(A发送最后的ACK时间 + B重传FIN=1的时间)当A收到B的FIN=1时候,再次发送最后的ACK,同事2MSL计时器重新启动
2.可能这时候还有很多从B发过来的报文(因为拥堵,或排队超时,被重传的那些报文)还在来的路上,但是这些报文已经无效了,为了防止A机器上新的连接收到这些报文,需要等这次报文超时。
TCP有限状态机
- 粗实线对应主动打开连接一方的状态变化
- 虚线对应被动打开连接一方的状态变化