Linux网络编程必备的POSIX API的细节

目录

POSIX API大集合

五元组

三次握手的过程, 内核协议栈分析

listen函数

DDOS攻击, 洪水攻击

DDOS 攻击的应对措施

数据发送

 怎么保证顺序?如何保证包地顺序到达(序号 + 确认应答机制 + 重传)

TCP断开连接的过程

问题1. 大量的CLOSE_WAIT + FIN_WAIT2是为啥?

time_wait状态存在的原因?


POSIX API大集合

Linux网络编程必备的POSIX API的细节_第1张图片

五元组

(sip, sport, dip, dport, protocol)

三次握手的过程, 内核协议栈分析

内核协议栈中是有内核数据结构的.   

我们send/write数据, 都是先发送到内核协议栈中,然后由内核协议栈封装发送到物理介质中传输到对端的

对端的接收过程也是经有内核协议栈进行解包, 最终对端应用层获取数据. 

Linux网络编程必备的POSIX API的细节_第2张图片 三次握手的过程是由客户端的用户通过connect系统调用发起的

由内核协议栈之间完成三次握手. 建立连接的.

第一次握手的时候, 会根据五元组生成一个 node 挂载到半连接队列syn队列中. 

第三次握手的时候会根据五元组的信息定位半连接队列中对应的node结点将其移动到accept queue中去.   

accept函数则是根据accept中的一个结点为其分配一个fd并且return 

Linux网络编程必备的POSIX API的细节_第3张图片

connect调用之后客户端处于 syn-sent状态  + 服务端接收到第一次握手数据包的时候处于  syn-recv状态.

listen函数

 int listen(int sockfd, int backlog);

unix系统中,backlog 是syn队列+accept队列的最大值;

linux系统中,backlog是accept队列的最大值。

至此我非常向提到一个东西叫做

DDOS攻击, 洪水攻击

eg : 在syn上做文章.  不断的向服务器发出syn请求, 请求和服务器建立连接, 恶意的占满服务器的syn队列. 使得正常的普通客户无法和服务器正常建立联系, 无法获取服务.

这个就算最为初级的syn洪水了

还可以利用反射机制,达到借刀杀人的效果

就是将目标服务器ip填写为源ip地址和其他机器请求建立连接.

这样其他机器误以为是服务器想要建立连接, 就会不断的向服务器发送syn + ack包, 这样服务器也会疲于处理大量的无效syn + ack包而无法正常运作

甚至还有更为牛逼的放大攻击.

利用服务器的ip地址发送DNS请求, 然后对于DNS请求而言, 一般是发送一个请求报文远远小于响应报文的, 这样就可以达到放大的效果. 放大垃圾数据攻击服务器.

DDOS 攻击的应对措施

在服务器前面放一台巨大的堡垒机. 让其拦截掉恶意请求.过滤连接请求. 达到净化的效果

数据发送

其实针对数据的send/write是从用户态拷贝到内核协议栈的内核缓冲区中的,然后由内核协议栈不断地进行层层封包, 最后放到物理介质传输到对端, 对端接收到数据报, 在根据头部信息分用, 最终将数据传到应用层

Linux网络编程必备的POSIX API的细节_第4张图片

 怎么保证顺序?如何保证包地顺序到达(序号 + 确认应答机制 + 重传)

延迟ack,解决包的有序的问题. 就不见ack, 会在最近序号没有收到ack位置及其之后所有的包全部重传, 这样就可以保证一定是顺序到达地. 后面地包先到也没用,还是会丢弃重传. (保证顺序)

Linux网络编程必备的POSIX API的细节_第5张图片

重传费带宽, 所以有些时候需要考虑udp, 比如在弱网环境下, 也就是网络环境非常差劲地情况下.

实时性强的场景,也可以选择udp

udp使用场景:

  1. 游戏,利用UDP的实时性;
  2. 迅雷下载,使用UDP传输,抢占带宽;TCP有拥塞控制,对带宽进行控制。

TCP断开连接的过程

Linux网络编程必备的POSIX API的细节_第6张图片

 tcp连接的断开过程. 是由客户端发起的close。然后内核协议栈会向对端发送一个fin包, 同时主动发起方进入fin_wait1状态, 然后对端收到fin包,先回一个ack然后被动的进入close_wait状态. 为何此处的fin + ack不可以何在一起, 因为服务器端很可能还需要向客户端发送未发送完的数据. 发送完之后才会进行close.

问题1. 大量的CLOSE_WAIT + FIN_WAIT2是为啥?

服务端没有处理断开连接的逻辑, 收到客户端的fin包,关闭了读端之后没有进行close。(没有close的逻辑)

time_wait状态存在的原因?

避免最后一次ack的丢失, 如果服务器久收不到客户端发送过来的ack包,也就是被动方久收不到ack就会重新发送fin,这个时候不等,不就没了嘛。 为了让服务端正常断开这条连接, 于是等待time_wait = 2MSL。

你可能感兴趣的:(后端服务器开发,学习,协议栈,网络编程,服务器,linux)