文章目录
- (1) 三次握手各状态
- CLOSE状态
- SYN_SENT状态
- SYN_RECV状态
- ESTABLISHED状态
- (2) 为什么握手时的seqnum是随机值,以及acknum的功能
- (3) 三次握手中的半连接队列(SYN队列)和全连接队列(ACCEPT队列)
- 半连接队列
- 全连接队列
- (4) 怎么缓解SYN泛洪
- (5) TCP实现P2P
- (6) 为什么需要三次握手?
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/3d85bd3fd0f84981934e0de37766427c.png#pic_center)
(1) 三次握手各状态
CLOSE状态
发起连接和listen之前的初始状态
SYN_SENT状态
第一次握手,客户端向服务器发起连接请求,发送一个SYN数据包,该数据包中包含了客户端的初始序列号等信息,用于请求与服务器建立TCP连接
SYN_SENT: 初始状态发送SYN报文后,即进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。
SYN_RECV状态
第二次握手,服务器接着会向客户端发送一个SYN+ACK数据包,这是对客户端SYN请求的响应。该数据包包含了服务器的初始序列号以及对客户端SYN包的确认信息,表示服务器同意与客户端建立连接。
SYN_RCVD: 这个状态表示LISTEN状体时接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态
ESTABLISHED状态
第三次握手,客户端收到服务器的SYN+ACK包后,会 向服务器发送一个ACK数据包 ,用于确认收到了服务器的SYN+ACK包。这个ACK包标志着客户端和服务器之间的TCP连接已经基本建立成功,此时连接处于ESTABLISHED状态。
当服务端收到收到ack包以后会进入ESTABLISHED状态。
(2) 为什么握手时的seqnum是随机值,以及acknum的功能
在第一次握手的时候,tcp包头部的Sequence number是一个随机值,就算自己随便设置一个值后续的TCP连接也是可以正常运作的(上图的seqnum = 1234),但是在第二次握手回复的TCP包中的acknum会比第一次握手的Sequence number多一(acknum 1235),这里的1235表示表示 1235以前的所有包都收到了,作用:保证了tcp包的不丢失,不重复
包括第二次握手时服务端发出的seqnum也是随机值(4567),但是第三次握手时的acknum是seqnum+1(4568)
作用:避免被抓包以后被别人知道之前发过多少个包
(3) 三次握手中的半连接队列(SYN队列)和全连接队列(ACCEPT队列)
半连接队列
当服务器收到客户端发送的 SYN 报文段时,会创建一个半连接节点并放进半连接队列,该节点记录了该连接的相关信息,如客户端的 IP 地址、端口号等,此时连接处于半连接状态,
SYN队列的作用:在服务器处理能力有限的情况下,SYN 队列可以暂时缓存客户端的连接请求,避免因为同时处理过多连接请求而导致系统崩溃。
全连接队列
服务器收到客户端的ACK包后,会检查这个ACK包的合法性和有效性,如确认序列号是否正确等。如果检查通过,服务器会将对应的连接从SYN队列中取出,并放入accept队列。Accept 队列用于存放已经完成三次握手的 TCP 连接,此时,应用程序就可以通过调用accept系统调用从accept队列中获取已经建立好的连接,开始进行数据传输等操作。
Accept队列的作用:
(1)Accept 队列将网络层已经建立好的连接与应用层的处理隔离开来。应用层可以按照自己的节奏从 Accept 队列中获取连接,而不会受到网络层连接建立速度的直接影响。
(2)缓冲连接数据:在应用程序暂时无法处理新连接时,Accept 队列可以作为一个缓冲区域,存储这些已经建立的连接,避免连接因为等待处理时间过长而出现问题。
(4) 怎么缓解SYN泛洪
(1)net.ipv4.tcp_max_syn_backlog:在 Linux 系统中,该参数用于设置 SYN 队列的最大长度。默认值通常为 1024 或 2048,可以根据服务器的性能和实际需求进行调整。
通过限制 SYN 队列的长度,可以在一定程度上抵御 SYN Flood 攻击。当 SYN 队列已满时,服务器会丢弃新的 SYN 请求,从而避免被大量伪造的 SYN 报文淹没。
(2)somaxconn:这是系统级别的参数,用于限制 Accept 队列的最大长度。在不同的操作系统中,默认值可能不同。例如在 Linux 中,默认值通常为 128。
listen(int socketfd, int backlog):在网络编程中,listen 函数的 backlog 参数用于设置服务器端监听套接字的 Accept 队列长度。它会覆盖系统默认的 somaxconn 值,但通常不能超过 somaxconn。
当 Accept 队列已满时,服务器会拒绝新的 SYN 请求,从而避免服务器因处理大量的 SYN 请求而耗尽资源,在一定程度上可以缓解 SYN 泛洪攻击对服务器造成的影响。
(5) TCP实现P2P
P2P中没有客户端和服务端的概念
(6) 为什么需要三次握手?
三次握手的主要目的是为了确认服务器端和客户端的发送和接受能力是否正常
-
第一次握手:客户端发送网络包,服务端收到了。 这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
-
第二次握手:服务端发包,客户端收到了。 这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
-
第三次握手:客户端发包,服务端收到了。 这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
假设只有两次握手。
当客户端发送第一个SYN,但由于网络延迟或其他原因,第一个SYN没有及时到达服务端,于是客户端又发送一次SYN,这次的SYN成功到达了服务端,在连接结束后,第一个SYN终于到了服务端,此时服务端以为客户端再次发起连接请求,于是回复ACK+SYN导致再次连接再次建立,浪费资源