之前说到TCP是传输层,它能够把数据准确可靠的传给对方。TCP协议采用了“三次握手”
策略,那么什么是三次握手呢
?
三次握手

第一步:
客户端
主动打开,发送连接请求报文段
,将SYN
标识位置为1
,然后发送Sequence Number
置为x
(TCP规定SYN=1
时不能携带数据,x
为随机产生的一个值),然后进入SYN_SEND
状态。
第二步:
服务器
收到请求报文,将SYN
标识位置为1
,ACK
置为1
,Sequence Number
置为y
,Acknowledgment Number
置为x+1
,然后进入SYN_RECV
状态,这个状态被称为半连接状态。
第三步:客户端再进行一次确认,将
ACK
置为1
(此时不用SYN),Sequence Number
置为x+1
,Acknowledgment Number
置为y+1
发向服务器,最后客户端与服务器都进入ESTABLISHED
状态
再来说一下这些字符代表的意思:
SYN:代表请求创建连接,所以在三次握手中前两次要
SYN=1
,表示这两次用于建立连接。
ACK:代表确认接受,不管是三次握手还是四次分手,在回应的时候都会加上
ACK=1
,表示消息接收到了,并且在建立连接以后的发送数据时,都需加上ACK=1
,来表示数据接收成功。
seq:序列号,什么意思呢?当发送一个数据时,数据是被拆成多个数据包来发送,序列号就是对每个数据包进行编号,这样接受方才能对数据包进行再次拼接。
ack:这个代表下一个数据包的编号,这也就是为什么第二次请求时,
ack
是seq+1
。
明明第二次握手过后就可以进行数据传输了,为什么要三次握手呢?
如果是两次握手,我们想象一下,服务器收到客户端发来的连接请求,然后回复收到,连接就已经建立了。可是会出现这样一种问题,由于网络状态不好,我发送了连接请求,可是它走的特别慢,服务器半天没有收到,我又发了一个请求,这时第二个请求到位了,建立了连接,我们就开始传输数据,直到断开连接,可是有这么一种可能,第一个请求很顽强经历了长时间的跋涉终于到达了服务器,这时服务器收到又建立起了连接,可是这时候我根本不知道再次建立了连接,这就造成了极大的资源浪费,因此加入第三次握手告知服务器收到回应,可以建立连接,就可以避免这种情况的发生。
四次挥手

TCP
断开连接则被我们称为“四次挥手”,当客户端没有数据需要发送给服务器时就需要释放连接,我们来看看其具体步骤。
这里出现了一个连接时没有出现的字符:
FIN:表示请求关闭连接,在四次分手时,我们发现
FIN
发了两遍。这是因为TCP
的连接是双向的,所以一次FIN
只能关闭一个方向。
1.客户端发送一个报文给服务端(没有数据),其中
FIN
设置为1
,Sequence Number
设置为u
,客户端进入FIN-WAIT-1
的状态。
2.服务器收到客户端的请求,发送一个
ACK=1
给客户端,表示收到请求,ack
置为u+1
,发送一个Sequence Number
为v
,服务器进入CLOSE-WAIT
状态。
3.服务器发送一个
FIN=1
,ACK=1
给客户端,Sequence
置为w
,Acknowledge
置为u+1
,用来关闭服务端到客户端的数据传送,服务端进入LAST_ACK
状态。
4.客户端收到
FIN
后,进入TIME_WAIT
状态,接着发送一个ACK
给服务端,Acknowledge
置为w+1
,Sequence Number
置为u+1
,最后客户端和服务端都进入CLOSED
状态。
为什么要四次挥手
为什么要四次挥手才能断开连接,当服务器收到FIN时,这说明客户端不会再给你传输数据了,但是服务器可能还有一些数据没有传给客户端,还需要将数据发完才会发送FIN
给客户端告诉对方同意关闭,客户端再回应收到服务器的关闭请求,服务器进入关闭状态,客户端再2MSL
后进入关闭状态。
为什么要等待2MSL后才返回CLOSE状态
双方既然都同意了关闭连接,按理说可以直接close
,但是我们必须假象网络是不可靠的,无法保证最后的ACK
一定被收到,因此对方可能收不到重新发送FIN
,所以2MSL
就是用来重发可能丢失的ACK
报文。
网友评论