TCP Three-way Handshake
In TCP (Transmission Control Protocol), 3-way handshaking is the process of establishing a connection between two devices over a network. It involves three steps:
- The sending device (client) sends a
SYN(synchronize) packet to the receiving device (server). - The receiving device responds with a
SYN-ACK(synchronize-acknowledgment) packet. - The sending device responds with an
ACK(acknowledgment) packet.
This completes the 3-way handshake and the connection is established.
三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。
刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态。
第一次握手
- 客户端给服务端发一个
SYN报文,并指明客户端的初始化序列号ISN,此时客户端处于SYN-SENT状态。 - 首部的同步位
SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但要消耗掉一个序号。
第二次握手
- 服务器收到客户端的
SYN报文之后,会以自己的SYN报文作为应答,并且也是指定了自己的初始化序列号ISN。同时会把客户端的ISN + 1作为ACK的值,表示自己已经收到了客户端的SYN,此时服务器处于SYN-REVD的状态。 - 在确认报文段中
SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y
第三次握手
- 客户端收到
SYN报文之后,会发送一个ACK报文,当然,也是一样把服务器的ISN + 1作为ACK的值,表示已经收到了服务端的SYN报文,此时客户端处于ESTABLISHED状态。服务器收到ACK报文之后,也处于ESTABLISHED状态,此时,双方已建立起了连接。 - 确认报文段
ACK=1,确认号ack=y+1,序号seq=x+1(初始为seq=x,第二个报文段所以要+1),ACK报文段可以携带数据,不携带数据则不消耗序号。
TCP 三次握手的建立连接的过程就是相互确认初始序号的过程,告诉对方,什么样序号的报文段能够被正确接收。 第三次握手的作用是客户端对服务器端的初始序号的确认。如果只使用两次握手,那么服务器就没有办法知道自己的序号是否已被确认。同时这样也是为了防止失效的请求报文段被服务器接收,而出现错误的情况。
三次握手的必要性
那为什么要三次握手呢?两次不行吗?這是为了确认双方的接收能力和发送能力都正常:
- 第一次:客户端什么都不能确认。服务端能确认客户端的发送正常,自己的接收正常
- 第二次:客户端能确认自己的发送和接收正常,服务端的发送和接收正常。服务端能确认自己接收正常,客户端的发送正常。
- 第三次:全部都能确认了。
如果是用两次握手,只要服务端发出确认,就建立新的连接的話,可能会出现下面这种情况:
- 如客户端发出连接请求,但因某些原因未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接。
- 第一个报文段原來只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,
- 此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,
- 此时客户端忽略服务端发来的确认,也不发送数据,则服务端一直等待客户端发送数据,浪费资源。