TCP 的三次握手和四次挥手
序号和确认号
- 从 TCP 连接建立的开始,到 TCP 连接的断开,你要传输的所有数据的每一个字节都要编号,这个序号称为 字节序号
- 如果一个 TCP 报文的 报文序号 为 301,它携带了 100 字节的数据,就表示这 100 个字节的数据的字节序号范围是 [301, 400],该报文携带的第一个字节序号是 301,最后一个字节序号是 400
- 每传送一个 TCP 报文都要等待对方回复一个确认,但这种方式效率太低,在 TCP 协议中,一般采用累积确认的方式,即每次传送多个连续 TCP 报文,可以只对最后一个 TCP 报文进行确认。对方通过回复一个 确认号 来表示已经接收到了哪个 TCP 报文。比如发送方发送了一个序号为 301 的 TCP 报文,这个报文携带了 100 字节数据,则接收方应当回复的确认号是 401,它表示接收方已经收到了字节序号为 [300, 400] 的数据,现在期望你发送字节序号为 401 以及以后的数据
SYN、ACK 和 FIN
ACK
:TCP 协议规定,只有ACK=1
时有效,也规定连接建立后所有发送的报文的ACK
必须为 1SYN
:在连接建立时用来同步序号。当SYN=1
而ACK=0
时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1
和ACK=1
。因此SYN
置 1 就表示这是一个连接请求或连接接受报文FIN
:用来释放一个连接。当FIN=1
表明此发送方的数据已经发送完毕并要求释放连接
三次握手和四次挥手
TCP 需要建立一条可靠的连接,那么对于一条可靠的连接来说,最起码的是发出去的请求能收到对方的确认。所以 Client 发送 SYN
并受到 ACK
后,才能确认连接建立,同样 Server 也需要发送 SYN
并受到 ACK
才能确认建立连接,这样最少需要三次请求,也就是 三次握手
TCP 是全双工模式,也就是双方可以同时发送和接收消息。Client 发送 FIN
并收到 ACK
只是确认了 Client 没有更多数据需要传输,此时 Client 不能关闭连接,因为 Server 可能还会有数据传输过来。而当 Server 发送 FIN
并收到 ACK
后,双方都确认没有更多的消息需要传递,于是关闭连接。这样最少需要 四次挥手
四次挥手之所以比三次握手多一次是因为:
- TCP 需要建立连接后才能传输数据,于是乎在建立连接的过程中肯定没有数据报文,可以把
SYN
和ACK
合并为一个报文节省流量 - 而断开连接时,Server 回复
ACK
响应 Client 的FIN
后,Server 依然可以继续发送报文,此时 Client 进入等待状态继续接收 Server 报文直到 Server 发送完毕并发送FIN
,FIN
和ACK
并不能合并为一个报文