05-TCP的3次握手

目标

  • 知道 TCP 的 3 次握手是用于建立连接

所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,

image-20180907233721841

整个流程如下图所示:

image-20180630092755719

(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。      

(2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。      

(3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

tcp

常见面试题

为什么需要三次握手,两次不可以吗?或者四次、五次可以吗?

两次握手不可以的原因:

我们来分析一种特殊情况,如果两次握手就可以确认连接,假设客户端请求建立连接,发给服务器SYN包等待服务器确认,服务器收到后,回复客户端数据包以确认连接请求,服务器认为连接已经建立。服务端开始给客户端发送数据。

但服务端回复的确认请求可能因为各种原因丢失 ,客户端认为连接没有建立,会进行重传。假设每次发送的数据一直在丢失,客户端一直SYN,服务器就会产生多个无效连接,占用资源,这个时候服务器可能会挂掉。这个现象就是我们听过的“SYN的洪水攻击”。

所以要求客户端进行第三次握手确认连接,这样服务器才可以放心的把数据传给客户端。

总结: 第三次握手是为了防止这种情况:如果客户端迟迟没有收到服务器返回确认报文,这时会放弃连接,重新启动一条连接请求。但问题是:服务器不知道客户端没有收到,所以他会收到两个连接,浪费连接开销。如果每次都是这样,就会浪费多个连接开销。

多于三次的握手没有必要,浪费资源,降低速度。