1、tcp报文格式
序号:Seq序号,占32位,用来标识从源端向目的端发送的字节流
确认序号:Ack序号,占32位,只有当ACK标志为1时,该序号才有效,ack=seq + 1
标志位:共六个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
(A)URG:紧急指针(urgent pointer)有效。
(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置连接。
(E)SYN:发起一个新连接。
(F)FIN:释放一个连接。
![](https://img.haomeiwen.com/i10840213/37e40563615e6440.png)
2、三次握手
![](https://img.haomeiwen.com/i10840213/ae4f39359dfafdd0.png)
(1)Client向Server发送同步确认包,将标志位SYN=1,发送序列号seq=j,然后Client变成SYN_SEND状态
(2)Server收到之后,发送SYN+ACK包。将标志位ACK=1,确认序列号ack=seq+1。将标志位SYN=1,序列号seq=k。然后Server变成SYN_SEND状态
(3)Client收到确认后,检查ack是否为j+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了
3、四次挥手
![](https://img.haomeiwen.com/i10840213/25eda16e713bfcd5.png)
(1)Client发送FIN包,将FIN标志位设置为1,发送序列号seq=j,Client进入FIN_WAIT_1状态
(2)Server收到该请求后,发送确认包,将标志位ACK设置为1,发送确认序列号ack=j+1,Server进入CLOSE_WAIT状态。因为Server端此时有可能还有数据要发送,只是给客户端发送了我知道你要关闭了,但是我还有数据要发送。然后可以继续发送数据
(3)如果Server端把数据发送完之后,再给客户端发送一个FIN包,将FIN标志位设置1,发送序列号seq=k。然后进入LAST_ACK状态。
(4)Client收到之后,发送确认包,将标志位ACK设置为1,ack=k+1。随后双方进入CLOSED状态
假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!
网友评论