【Linux】三次握手

客户端connect()向服务器发起连接,客户端和服务器通过三次握手建立连接,被服务器listen()开机后监听到后将套接字放到listen()已完成三次握手队列中。

第一次握手:建立连接时,客户端向服务器发送SYN报文(seq = j),并进入SYN_SENT状态,等待服务器确认。

第二次握手:服务器收到SYN报文,必须确认客户的SYN(即发送ACK报文,ack = j+1),同时自己也发送一个SYN报文(seq = k),即ACK+SYN报文,此时服务器进入SYN_RECV状态。

第三次握手:客户端收到服务器的SYN+ACK报文,向服务器发送确认报文ACK(ack = k+1),此报文发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态。完成三次握手。

未完成三次握手队列:在三次握手协议中,服务器listen()维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处SYN_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。

三次握手示意图

三次握手的作用:

使得通讯双方都做好通讯的准备

告诉对端,本端通讯所选用的报文标识号

       防止已失效的连接请求报文段又突然传递到了服务端,从而产生错误

为什么是三次握手,两次可以吗?

不可以。主要目的是防止服务器一直等待,浪费资源。举例说明:

客户端发出的第一个连接请求报文段并没有丢失,而是在某个网络节点长时间的滞留了,以至于延误到连接释放以后的某个时间才送达服务器。本来这是一个早已失效的报文段,但是服务器收到此失效的连接请求报文段后,就误以为是客户端再次发出了一个新的连接请求;于是就向客户端发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要服务器发出确认,新的连接就建立了。由于现在客户端并没有发出建立连接的请求,所以不会理睬服务器的确认,也不会向服务器发送数据。但服务器却以为新的运输连接已经建立,并一直等待客户端发来数据。这样服务器的很多资源就白白浪费掉了。

采用“三次握手”的办法可以防止上述现象发生。例如发生上述现象。客户端不会向服务器的确认发出确认。服务器由于收不到确认,就知道客户端并没有要建立连接。

三次握手哪个阶段会出现异常?

阶段可能会出现异常。如果服务器相应的端口未打开,会回复RST复位报文,握手失败

此外,listen创建的监听队列达到上限,也可能失败。

三次握手哪个阶段容易出现攻击?

比较典型的是SYN泛洪攻击,或叫SYN溢出攻击

syn溢出攻击,即出现在第二阶段,如果客户机伪造出大量第一次的syn同步报文,服务器就会依次耗掉很多资源来保存客户端的信息,并进行确认,实际确认是会失败的,但失败是需要一定时间的,因为服务器会连续多次进行第二次握手确认后才认定失败。那么短时间内有大量syn同步报文涌向服务端,服务器资源可能被耗尽,就可能导致正常的客户端得不到响应而失败

发布了20 篇原创文章 · 获赞 24 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ifiwere/article/details/104599132