TCP 协议
一、连接建立与关闭
Header Format
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Port | Destination Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Acknowledgment Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data | |U|A|P|R|S|F| | | Offset| Reserved |R|C|S|S|Y|I| Window | | | |G|K|H|T|N|N| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Checksum | Urgent Pointer | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TCP Connection State Diagram
+---------+ ---------\ active OPEN | CLOSED | \ ----------- +---------+<---------\ \ create TCB | ^ \ \ snd SYN passive OPEN | | CLOSE \ \ ------------ | | ---------- \ \ create TCB | | delete TCB \ \ V | \ \ +---------+ CLOSE | \ | LISTEN | ---------- | | +---------+ delete TCB | | rcv SYN | | SEND | | ----------- | | ------- | V +---------+ snd SYN,ACK / \ snd SYN +---------+ | |<----------------- ------------------>| | | SYN | rcv SYN | SYN | | RCVD |<-----------------------------------------------| SENT | | | snd ACK | | | |------------------ -------------------| | +---------+ rcv ACK of SYN \ / rcv SYN,ACK +---------+ | -------------- | | ----------- | x | | snd ACK | V V | CLOSE +---------+ | ------- | ESTAB | | snd FIN +---------+ | CLOSE | | rcv FIN V ------- | | ------- +---------+ snd FIN / \ snd ACK +---------+ | FIN |<----------------- ------------------>| CLOSE | | WAIT-1 |------------------ | WAIT | +---------+ rcv FIN \ +---------+ | rcv ACK of FIN ------- | CLOSE | | -------------- snd ACK | ------- | V x V snd FIN V +---------+ +---------+ +---------+ |FINWAIT-2| | CLOSING | | LAST-ACK| +---------+ +---------+ +---------+ | rcv ACK of FIN | rcv ACK of FIN | | rcv FIN -------------- | Timeout=2MSL -------------- | | ------- x V ------------ x V \ snd ACK +---------+delete TCB +---------+ ------------------------>|TIME WAIT|------------------>| CLOSED | +---------+ +---------+
TCP 连接建立(三次握手)
- A(CLOSED) -> 主动打开,发送 SYN -> A(SYN-SENT)
- B(CLOSED) -> 收到 SYN,被动打开 -> B(LISTEN) -> 回复 SYN,ACK -> B(SYN-RECEIVED)
- A(SYN-SENT) -> 收到 SYN,ACK,发送 ACK -> A(ESTABLISHED)
- B(SYN-RECEIVED) -> 收到 ACK -> B(ESTABLISHED)
TCP 关闭建立(四次挥手)
- A(ESTABLISHED) ->主动发送 FIN -> A(FIN-WAIT-1)
- B(ESTABLISHED) -> 收到 FIN,发送 ACK -> B(CLOSE-WAIT)
- A(FIN-WAIT-1) -> 收到 ACK -> A(FIN-WAIT-2)
- B(CLOSE-WAIT) -> 发送 FIN -> B(LAST-ACK)
- A(FIN-WAIT-2) -> 收到 FIN,发送 ACK -> A(TIME-WAIT) -> 等待 2MSL -> A(CLOSED)
- B(LAST-ACK) -> 收到 ACK -> B(CLOSED)
由于拜占庭将军问题(Two Generals Problem),不可能保证两个对等点都能实现干净的关闭
二、滑动窗口
解决网络传输中的问题:丢包和重复包,包出错,包传输乱序
实现:维护一个发送方和接收方的缓冲区
正常情况下:
窗口中的数据已发送的在等待回应,一旦有回应窗口就会前进,待发送的会发出去
当 4 号数据包得到回应后如下图,8、9 号包被发送了出去,并把 11 号包读了进来
丢包(Ack,确认字符)情况下:
窗口中的数据已经全部发送,但是没有拿到 5 号包的回应(Ack)就一直等待,对方如果收到了 5 号后的包是不会发 Ack 的,要保证数据包的传输顺序
如果一直没有收到 Ack,TCP 协议有超时重传机制,会重新从 5 号包开始发,下图就是重发后对方收到了 5 号包,并把之前确认过的包的 Ack 一起发送了过来
https://www.rfc-editor.org/rfc/rfc793.html
https://coolshell.cn/articles/11564.html & https://coolshell.cn/articles/11609.html