1. TCP特点
-
可靠传输
TCP将对数据报编号作为序列号,接收方收到数据将对数据报进行排序;传输时具有超时重传和确认应答机制,数据发送后将启动定时器,对端收到TCP数据将返回确认,发送发如果到时间没收到确认将重传数据报;
TCP具有流量控制和拥塞控制等机制;
-
面向连接
开始传递数据前,TCP需要三次握手建立连接;
2. 首部
-
源端口、目标端口
TCP提供端到端的服务,端口号占用2字节,且网络传输时使用大端 -
序号
TCP提供可靠传输,会对数据的每个字节编号,序列号为当前传输字节流中第一个字节的编号;根据编号可以对数据报进行排序,再传递给应用层;
-
确认号
TCP具有应答机制,收到数据报后,需要根据收到的序号返回确认号,表示对方下次传递的数据第一个字节对应编号; -
数据偏移
首部长度,表示首部有多少个四字节,取值0101 ~ 1111, TCP首部长度在20 ~ 60字节; -
标志位
URG:表示报文段中有紧急数据,要优先传递;
ACK:使用确认号,此位要置为1;
PSH:尽快传递;
RST:重新建立连接
SYN:建立连接请求
FIN:释放连接请求 -
窗口
接收窗口大小,提供流量控制
3. 流量控制及拥塞控制
3.1 流量控制
TCP缓冲区有固定大小,定义在首部窗口字段,也就是滑动窗口,窗口信息位于首部可以和对端共享信息,因此发送方可以根据该信息控制发送速率,发送数据大小不能超过接收方窗口大小,防止对方缓冲区溢出
3.2 拥塞控制
TCP根据网络拥塞状态调整拥塞窗口大小,发送窗口大小要是拥塞窗口和对端接收窗口二者中的最小值;
滑动窗口信息可以两端共享,但是拥塞窗口信息只属于本地,根据网络状态,拥塞窗口大小调整遵循如下规律:慢启动、拥塞避免、乘法减小;
- 慢启动
拥塞窗口初始值较小,随着数据包成功传递,窗口大小成倍增长; - 拥塞避免
存在一拥塞阈值,当拥塞窗口大小达到阈值,则不再成倍增长,开始线性增大,防止过快出现拥塞现象; - 乘法减小
当出现数据包丢失情况,拥塞阈值设为峰值的一半,拥塞窗口恢复到初始值,再次开始慢启动; - 快恢复
数据包丢失后,快恢复机制是,阈值设为峰值一半,但是拥塞窗口不设为初始值,而是设为新阈值的大小,然后接着直接开始拥塞避免,拥塞窗口线性增大;
4. 连接建立/终止及TCP状态
4.1 建立连接
-
连接图
-
三次握手过程
- 起始客户端、服务端都处于
CLOSED
状态 - 服务端调用socket api----accept后进入
LISTEN
监听状态 - 客户端调用socket api----connect请求建立连接,将发送SYN包,SYN位为1,且明确序列号值,进入
SYN-SENT
状态 - 服务端收到SYN包,将返回一个SYN、ACK包,SYN、ACK位为1,且明确自己的序列号,确认号为收到的SYN包中序列号加1,服务端进入
SYN-RCVD
状态 - 客户端收到返回的确认,将返回一个ACK包,ACK位为1,序列号为收到的包中的确认号,确认号为收到的包中的序列号加1,客户端进入
ESTABLISHED
状态,connect返回socket - 服务端收到ACK包后,进入
ESTABLISHED
状态,三次握手结束,accept返回socket
- 起始客户端、服务端都处于
-
两次、四次握手
两次握手:只能满足发送端的序列号被确认,另外两次握手造成超时的连接请求到达服务端后也能建立连接,造成服务端资源浪费;四次握手:两边各发SYN,对端返回ACK,浪费时间,第二次、第三次握手可以合并,即变为三次握手;
4.2 连接终止
-
终止图
-
四次挥手过程
- 起始两端都属于
ESTABLISHED
状态 - A端发送FIN包,FIN位为1,进入
FIN_WAIT1
状态 - B端收到FIN包,将返回ACK包,进入
CLOSE-WAIT
状态,表示等待关闭 - A端收到ACK包,进入
FIN_WAIT2
状态 - 二次挥手、三次挥手之间,B端还可以给A端发送数据
- B端也没数据发时,发送FIN包,进入
LAST_ACK
状态 - A端收到FIN包,返回ACK包,进入
TIME_WAIT
状态 - B端收到ACK包,进入
CLOSED
状态 - A端等待2MSL,进入
CLOSED
状态
- 起始两端都属于
-
为什么要四次挥手
TCP是全双工通信,每个方向都有单独关闭 -
为什么发起端最后要有
TIME_WAIT
状态
发起端要在TIME_WAIT
状态等待2MSL,MSL表示报文在网络中的最长生存时间,等待2MSL再关闭可以确保下一次的新连接不会被本次连接产生的数据包干扰
5. 其他机制
- 延时确认
收到数据后不立刻确认,根据定时器,到时间后检查是否要发送ACK,这样对多个连续分组只发送最终ACK即可 - 快重传
- 保活定时器