TCP三次握手详解

272 阅读2分钟

image.png

TCP三次握手的过程如下

第一次握手: 客户端将标志位SYN设置为1,发送随机序号seq = x,希望收到x + 1的ack确认号,进入SYN-SENT状态

第二次握手: 服务器将SYN和ACK设置为1,ack确认号 = x + 1,进入SYN-RCVD状态

第三次握手: 客户端确认服务器的SYN分组,进入ESTABLISHED状态

为什么需要三次握手?

为什么需要三次握手也等于问为什么不是两次握手和四次握手?

一、两次握手不能确保双方初始序列号的同步和收发功能的正常,可能造成资源的浪费,因为如果只有两次握手,那么服务器在发送完SYN-ACK后并不能知道客户端是否成功接收分组就进入established状态,创建缓存等资源,如果分组在传输的路上丢失了,那么服务器就会长时间等待客户端发送数据,造成不必要的资源浪费。

二、四次握手的就是服务器先发送ACK,在发送SYN,三次握手就是将四次握手的第二三步合在一起,减少建立连接的时延。三次握手已经能满足TCP可靠连接的建立,所以不需要四次握手

如果双方同时发起连接的建立呢,会发生什么?

image.png

1.服务器和客户端同时发出SYN报文,等待收到对方的ACK报文

2.当收到对方的SYN报文时,会发送SYN-ACK报文,再次等待对方的ACK确认报文

3.当收到对方的SYN-ACK后建立连接成功

什么原因会造成SYN报文被丢弃?

假设该服务器正遭受SYN攻击(客户端发送大量SYN,但是不完成第三次握手),当服务器收到SYN后会将该连接放入半连接队列,当服务器半连接队列满了,后面到来的SYN就会被丢弃。

如何避免SYN攻击呢?

如果开启了syn-cookies 功能,就可以避免syn攻击,syn-cookies会在收到syn报文时先不将该连接放入半连接队列,而是通过源和目的端口和服务器密钥计算出一个cookie值,放入syn-ack报文中交给客户端,客户端在第三次握手时带上这个cookie,当服务器收到带有cookie的ack时,会重新计算发送该ack的客户端的源和目的端口,如果该值和cookie一样,代表是同一个客户端,这时直接间连接放入全连接队列,避免了syn攻击

小知识:TCP中syn的重传次数是6次,1秒,2秒,4秒,8秒,16秒,32秒

image.png