目录
三次握手
- 第一次握手:客户端将标志位置为1,随机产生一个值seq=J,并将该数据包发送给服务端,客户端进入SYN_SENT,等待服务器确认。
- 第二次握手:服务器端收到数据包后由标志位SYN=1知道客户端请求建立链接,服务器端将标志位SYN和ACK都置为1,ACK=J+1,随机产生一个值seq=K,并将数据包发送给客户端以确认连接请求,服务器进入SYN_RCVD状态。
- 第三次握手:客户端收到确认后,检查ACK是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ACK=K+1.并将该数据包发送给服务端,服务端检查ACK是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手。
四次挥手
- 第一次挥手:客户端发送一个FIN=M,用来关闭客户端到服务端的数据传输,客户端进入FIN_WAIT_1状态。
- 第二次挥手:服务器端收到FIN后,先发送ACK=M+1,告诉客户端你的请求我收到了,但是我没准备好,请继续等待我的消息。这个时候客户端进入FIN_WAIT_2状态,继续等待服务器端的FIN报文。
- 第三次挥手:当服务器端确认数据都已发送完成,则向客户端发送FIN=N报文,告诉客户端,好了我数据发送完了,准备好关闭连接了。服务器端进入LAST_ACK状态。
- 第四次挥手:客户端收到FIN=N报文后,就知道可以关闭连接了,但是他还是不相信网络,怕服务器不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器端收到ACK后,就知道要断开连接了。客户端等待了2MSL(最大报文段寿命)后依然没有收到回复,则证明服务器端以正常关闭,那客户端也可以关闭连接了,最终完成了四次握手。
TCP标志
SYN(同步):建立连接时用于同步序号。当SYN=1,ACK=0时表示这是一个连接请求报文段,若同意连接,则在响应报文段终使得SYN=1,ACK=1。因此SYN=1表示这是一个连接请求或连接接收报文。SYN只有在TCP建立来连接时才会被置为1,握手完成后SYN标志位被置为0。
ACK(确认):仅当ACK=1时,确认号ack字段才有效。ACK=0时,确认号ack字段无效。
FIN(终止):用来释放一个连接。FIN=1表示此报文的发送方的数据已经发送完毕,并要求释放传输连接。
seq(序列号):4字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生,给字节编上序号后,就给每一个报文段指派一个序号,seq就是这个报文段中的第一个字节的数据编号。
ack(确认号):4字节,期待收到对方下一次的seq,因此当前报文段seq+1就为确认号
ACK延迟确认
接收方在收到数据后,并不会立即回复ACK,TCP数据包到达的顺序时不保证的,接收方可能先接收到后发送的数据包,需要处理完之前的数据后才会进行ACK确认。另外就是ACK延迟确认机制,一般ACK会延迟200ms,这样是为了两个目的,一是便于合并ACK,如果连续收到两个TCP包,并不一定需要确认两次,只要回复最终的ACK就可以了,可以降低网络流量;二是如果接收方也有数据要发送,那么就会在发送数据的数据包里带上ACK信息,以减少网络流量。