Linux系统编程71 网络编程5 - TCP传输简析

可以发现 UDP方式传输中,是有大段时间在等待传输的,等ACK 发数据。

怎么样能快一点呢?

缩短等待时间:C端不是只发一次就开始等待,而是发送n个包,一直发,直到发满 RTT等待时间,即一直发,直到收到第一次ACK 为止,然后以后 每收到一个ACK 发一个包,这样的机制本质就是 把当前很多包扔出去,不等待,用包的数量最大限度抢占沿途传输的资源,沿途路由的等待队列其实是公共资源,大家都在用,所以一直发包 就可以抢占到沿途路由的等待队列,就算丢包也没关系,反正都有ACK编号,重新发就好了。

在这里插入图片描述
也就是说,一次性发出去n个包,并且这些包很有可能是走不同的路由路径,所以 S端先接收到哪个包也是不确定的,所以S端第一次返回的ACK 信号也是不一定第一个包的ACK,是不知道从哪个编号开始的,所以S端与C端在对话之前要进行编号约定:三次握手

在这里插入图片描述

连接开始时,连接建立方(Client)发送SYN包,并包含了自己的初始序号a;2. 连接接受方(Server)收到SYN包以后会回复一个SYN包,其中包含了对上一个a包的回应信息ACK,回应的序号为下一个希望收到包的序号,即a+1,然后还包含了自己的初始序号b;3. 连接建立方(Client)收到回应的SYN包以后,回复一个ACK包做响应,其中包含了下一个希望收到包的序号即b+1。

第一次握手:C端对S端说,我的编号从n开始,n不一定等于1。

第二次握手:
S端向C端发送ACK ,已经知道,你发给我的编号从n开始,我希望下一个收到的是序号为n+1的包
并且告诉C端,我的编号从m开始,m不一定等于1。

第三次握手:
C端向S端回复ACK,表示已经知道了 你的编号从m开始,下一个希望收到包的序号即m+1。

此时 S端知道了C端编号从n开始,C端知道了S端编号从m开始。

在这里插入图片描述

完成1,2 握手后,为半连接状态,之前S端会有一个池,叫半连接池,用来记录和S端 进行第1 2次握手的C端信息(IP 端口信息等),即记录和S端建立了半连接状态的节点。当发生第3次握手的时候,会在半连接池中找到C端信息,找得到的话 就可以继续传输了。

有一种攻击半连接池的攻击手段,叫做 半连接洪水,本质的手段就是用肉机占满S端的半连接池,即 只和S端进行前两次握手,就是不发送第三次握手,用来沾满半连接池,很下流。

解决办法:抛弃半连接池

用 cookie = 哈希((C端IP+C端端口 + S端IP + S端端口 + 约定的协议) | sort) 来校验,sort由内核产生,每秒变化一次。
第1 2 次握手 创建cookie,第三次用前面的cookie来验证身份。如果用当前sort计算出的cookie 和之前的cookie不同,则会用上一秒的sort重新计算一次,如果相同 即身份验证成功。在网络传输中,2秒中已经是一个非常长的时间了,所以只追溯上一秒的cookie。超过两秒,那就是网络条件不好。这样就能防止半连接洪水的攻击手段了。

Guess you like

Origin blog.csdn.net/LinuxArmbiggod/article/details/115499147