之前说到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报文。










网友评论