TCP基本认识
TCP定义
- 面向连接的、可靠的、基于字节流的传输层通信协议
TCP连接定义
- 用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合有Socket、序列号和窗口大小
TCP、UDP区别
1、连接
- TCP是面向连接的传输层协议,传输数据前要先建立连接
- UDP是不需要连接的,即刻传输数据
2、服务对象
- TCP是一对一的两点服务,即一条连接只有两个端点
- UDP支持一对一、一对多、多对多通信
3、可靠性
- TCP是可靠交付数据
- UDP是尽最大努力传输的,不保证可靠性
4、拥塞控制、流量控制
- TCP有拥塞控制、流量控制,保证数据传输的安全性
- UDP没有,网络拥塞也不会影响UDP的发送效率
5、首部开销
- TCP首部如果没有使用【选项】字段是20字节
- UDP首部只有8字节
6、传输方式
- TCP是流式传输,没有边界,但保证顺序和可靠谱
- UDP是一个包一个包的发送,有边界,但可能会丢包和乱序
7、分片不同
-
TCP的数据如果大于MSS大小,会在传输层分片
-
TCP的数据如果大于MTU大小,会在IP层分片
- MSS是MTU除去IP首部和TCP首部字节后的大小
- MTU指最大传输单元,一般IP协议是1500字节
TCP头部
-
序列号:在建⽴连接时由计算机⽣成的随机数作为其初始值,通过 SYN 包传给接收端主机,⽤来解决⽹络包乱序问题。 -
应答号:指下⼀次「期望」收到的数据的序列号,⽤来解决不丢包的问题。
-
控制位
- ACK:该位为
1
时,「确认应答」的字段变为有效 - SYN: 该位为
1
时,表示希望建⽴连接 - FIN: 该位为
1
时,表示今后不会再有数据发送,希望断开连接。 - RST: 该位为
1
时,表示 TCP 连接中出现异常必须强制断开连接
- ACK:该位为
TCP三次握手
-
开始握手状态
- 一开始客户端服务端都处于
CLOSE
状态 - 服务端进入
LISTEN
状态
- 一开始客户端服务端都处于
-
第一次握手
- 客户端发送SYN报文,请求序列号为客户端随机生成
- 客户端进入
SYN_SEND
状态
-
第二次握手
- 服务端收到SYN报文,确认应答,应答号为客户端请求序列化+1
- 服务端发起SYN报文,序列号为服务端随机生成
- 两次请求可以合成一次
- 服务端进入
SYN_RCVD
状态
-
第三次握手
- 客户端收到服务端发来的请求,确认应答,应答序列号为服务端序列号+1
- 客户端处于
ESTABLISHED
状态,服务端收到请求后同样处于ESTABLISHED
状态
为什么是三次握手,不是两次或者四次
-
因为三次握手才能确认双方都有发送和接收能力
-
防止重复历史连接的初始化
-
同步序列号
-
避免资源浪费
-
两次握手不能做到上述事情
-
四次握手是冗余的
TCP四次挥手
-
第一次挥手
- 客户端发送FIN报文
- 进入FIN_WAIT1状态
-
第二次挥手
- 服务端发送ACK报文
- 进入CLOSED_WAIT状态
- 客户端收到ACK报文后进入FIN_WAIT2状态
-
第三次挥手
- 服务端发送FIN报文
- 进入LAST_ACK状态
-
第四次挥手
- 客户端发送ACK报文
- 进入TIME_WAIT状态
- 如无异常 客户端会在2MSL后进入CLOSE状态
- 服务端在收到ACK报文后,进入CLOSE状态
- MSL(maximum segment lifetime):最大报文生成时间
为什么需要挥手四次
- FIN报文可以由任一方发起,客户端发送FIN报文,仅仅表示客户端不再发送数据了但是还能接收数据
- 服务端收到FIN报文后,需要先发送ACK报文确认收到,防止重发,服务端可能还有数据需要处理和发送,等服务端不再发送数据时,再发送FIN报文给客户端
为什么需要TIME_WAIT状态
-
防止具有相同四元组的旧数据包被收到
- 四元组是指【源IP 目标IP 源端口 目标端口】
- 经过2MSL时间,旧的数据包会自然小时
-
帮助被动关闭端正常关闭连接
- 如果发送的ACK报文在超过MSL时间内没有被服务端接收,
- 服务端就会重发FIN报文
- 这也说明了为什么TIME_WAIT等待的时间2MSL,即客户端的ACK报文和服务端重发FIN报文最久是2MSL
为什么TIME_WAIT等待的时间是2MSL
- 如果发送的ACK报文在超过MSL时间内没有被服务端接收,
- 服务端就会重发FIN报文
- 这也说明了为什么TIME_WAIT等待的时间2MSL,即客户端的ACK报文和服务端重发FIN报文最久是2MSL