网络通信笔记注解脚注(自用2)

网络协议栈

内核网络协议栈是操作系统内核中用于处理网络通信的一组网络协议功能 涵盖了多个OSI模型层级

通常包括以下组件

  • 网络接口控制层
  • 数据链路层
  • 网络层
  • 传输层
  • 网络套接字
  • 网络协议栈的控制和管理功能(内核负责管理控制整个网络协议栈运行,包括路由表维护,负载均衡,网络配置,防火墙等)

三次握手和四次挥手

三次握手

确保连接建立和释放的可靠性允许 双方通信时数据传输和管理的正确性

三次握手

① 客户端发送给服务端一个SYN报文[此报文段不能携带数据,但是要消耗一个序号],将初始序列号(ISN_C=x)随机发送给服务器,表示需要建立连接,此时客户端进入SYN_SENT状态
首部的同步位SYN=1,客户端初始化序号seq=x

②服务端收到客户端的SYN报文后会将自己的SYN报文作为应答,并且也将自己初始序列号(ISN_S)随机选择发送给客户端,同时对客户端的ISN_C+1进行确认作为ACK的值,表示已经发送到服务端,然后将报文段发送到客户端,此时服务端进入SYN_RCVD状态
在确认报文段中SYN=1,ACK=1,确认号ack=x+1,服务端初始化序号为seq=y

③ 客户端收到SYN报文后,会发送ACK报文,也是一样把服务器的ISN_S+1作为ACK的值,表示客户端已经收到了服务端的SYN报文,此时客户端处在了ESTABLISHED状态,在服务端收到了ACK报文后,也变成了此状态,此时双方就建立起了连接
确认报文段中ACK=1,确认号ack=y+1 序号seq=x+1(在此是客户端的第二个报文段了应该加一 )(ACK报文段可以携带数据,不携带数据则不消耗序号)

四次挥手
①客户端发送一个带有FIN(结束)标识的数据包,表示自己已经完成数据发送,要关闭数据发送通道,客户端进入FIN_WAIT_1状态
②服务端收到后,回复带有ACK标识数据包进行确认,同时服务端也发送一个带FIN标识的数据包,表示自己也完成发送,服务器进入CLOSE_WAIT状态,客户端进入FIN_WAIT_2状态
③客户端收到FIN后,对FIN进行确认,客户端进入TIME_WAIT状态,等待一段时间确保网络中所有延迟的数据包都能被接收和处理
④客户端等待段时间,发送最后一个ACK标示的数据包,确认服务器的FIN 此时客户端的TIME_WAIT状态结束,连接释放完成,服务器收到最后确认也完成释放

在这里插入图片描述

为什么是三次握手而不是两次

先弄清楚三次握手的目的

第一次:客户端发送网络包服务端收到
说明客户端发送能力,服务端接收能力正常
第二次:服务端发包客户端接收到
说明服务端的接收、发送能力正常,客户端接收发送能力正常

①不过此时服务端不能确认客户端的接收能力是否正常

第三次握手 客户端发包服务端收到
可以达到上述目的

②如果两次握手就导致客户端忽视服务端发出的确认,不断建立新的连接

如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。

半连接队列

在服务器首次接收到客户端的SYN后,会处于SYN_RCVD状态,此时双方没有完全建立连接,服务器会将此种状态下的请求放在一个队列里,这种队列叫半连接队列

全连接队列

已经完成三次握手,建立起来的连接
全连接中如果该队列满了会出现丢包现象

对于SYN-ACK确认包重传的问题:
当服务器发送完SYN-ACK包,如果未收到客户端的确认包,服务器就会进行首次重传,等待会仍未收到就会二次重传,如果重传次数超过系统最大次数,此连接信息会从办连接队列移除
重传等待时间一般指数增长,即间隔1s 2s 4s …
(确认包重传保证了第三次握手的可靠性,如果服务端没有收到客户端的回应,则不断重传包)

ISN序号规则

当一端为建立连接而发送SYN时,它为连接诶选择一个初始序号
ISN是随时间而变化的,因此每个连接都有不同ISN的,可以看作32位byte的计数器,每隔4ms增加1, 这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个连接它的一方对它作出错误的解释
在三次握手中,一个重要功能就是客户端和服务端互换ISN,以便让对方知道接下来接收数据时如何按照序列号组装数据; 如果ISN固定,攻击者很容易猜出后续确认号,因此ISN是动态生成的

三次握手中何时可以携带数据

其实第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据

为什么这样呢? 假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。

也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。

SYN攻击

服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。

检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。
netstat -n -p TCP | grep SYN_RECV

常见的防御 SYN 攻击的方法有如下几种:
缩短超时(SYN Timeout)时间
增加最大半连接数
过滤网关防护
SYN cookies技术

四次挥手

需要四次挥手是由于TCP的半关闭造成的
所谓的半关闭就是TCP提供了连接的一端在结束它的发送后还能接收另一端的数据能力
客户端服务端均可发起挥手动作

刚开始双方都处于ESTABLISHED状态如果客户端先发起关闭请求
四次挥手过程如下:

① 客户端发送一个FIN报文,报文中指定序号(seq=u)此时客户端处于FIN_WAIT1状态
发出连接释放报文段(FIN=1,序号seq=u),并停止发送数据主动关闭TCP连接,此时进入FIN_WAIT1状态,等待服务端确认
②服务端收到FIN后,发送ACK报文,并把客户端seq+1作为ACK报文的序号值,表明已经收到客户端的报文了,此时服务端处在CLOSE_WAIT(关闭等待)状态
此时TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端确认后进入FIN_WAIT2(终止等待状态) 等待服务端发出的连接释放报文段
③服务端也想断开连接了就和客户端第一次挥手一样发送FIN报文,且指定序列号,此时服务端处在LAST_ACK状态
即为服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1 ACK=1 序号seq=w 确认号:ack=u+1),服务端进入LAST_ACK(最后确认)等待客户端确认
客户端收到FIN 发送ACK报文应答 此时客户端处于TIME_WAIT状态,需要过一阵以保证服务端收到自己的ACK报文后才进入CLOSED状态,服务端收到ACK报文后,就处于关闭连接了,处于CLOSED状态
即客户端收到服务端的连接释放报文后发出确认报文(ACK=1 seq=u+1 ack=w+1)客户端进入TIME_WAIT(时间等待),此时TCP未释放,需要等时间计时器设置时间2MSL后,客户端进入CLOSED状态
客户端执行主动关闭进入TIME_WAIT 而服务端通常被动关闭不会进入此状态,在socket编程中,任一方执行close()操作即会产生挥手操作,收到一个FIN只意味着在这一个方向上没有数据流动。
在这里插入图片描述

为什么挥手要四次

  • 为什么不能像握手一样三次

握手时服务端收到客户端的SYN连接请求报文后可以直接发送SYN+ACK,ACK报文用来应答,SYN报文用来同步
但关闭连接时,当服务端收到FIN报文很可能不会立即关闭SOCKET 因此只能先回复一个ACK报文,告诉客户端发的FIN报文收到了,只有等服务端所有报文发送完了,才能发送FIN报文,因此不能一起发送

2MSL等待时间

2MSL等待状态也称为TIME_WAIT状态
每个具体TCP的实现必须选择一个报文段最大生存时间MSL(MAXimum Segment Lifetime)它是任何报文段被丢弃在网络内的最长时间
此时间段有限因为TCP报文段以IP数据报的形式在网络内传输而IP数据报有限制其生存时间的TTL字段。
MSL处理原则:
当TCP执行主动关闭并发回最后一个ACK,该连接必须在TIME_WAIT状态停留时间为两倍MSL
这样若另一端超时重发最后的FIN,可让TCP再次发送最后的ACK防止此ACK丢失

这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用。

  • 14
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值