socket编程的那些事儿

本文详细介绍了Python socket编程中的关键概念,包括SO_REUSEADDR选项、TIME_WAIT和CLOSE_WAIT状态及其解决方法。此外,还探讨了NAT的四种类型及其在通信中的影响,以及select模块的select函数参数解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、python的socket编程中socket.SO_REUSEADDR的含义:Socket中SO_REUSEADDR详解

2、socket编程的TIME_WAIT和CLOSE_WAIT状态:

(1)定义:TCP四次挥手时,主动发起断开连接的一方最后会进入TIME_WAIT状态,而被动断开连接的一方最后会进入CLOSE_WAIT状态:

(2)为什么需要TIME_WAIT状态?

a.防止上一次连接中的包,迷路后重新出现,影响新连接(经过2MSL,上一次连接中所有的重复包都会消失)
b.可靠的关闭TCP连接。在主动关闭方发送的最后一个 ACK(FIN) ,有可能丢失,这时被动方会重新发FIN, 如果这时主动方处于 CLOSED 状态 ,就会响应 RST 而不是 ACK。所以主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。另外这么设计TIME_WAIT 会定时的回收资源,并不会占用很大资源的,除非短时间内接受大量请求或者受到攻击。

(3)如何解决TIME_WAIT过多问题?

让服务器能够快速回收和重用那些TIME_WAIT的资源,如修改/etc/sysctl.conf文件的配置内容,修改完之后执行/sbin/sysctl -p让参数生效:

#对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃,不应该大于255,默认值是5,对应于180秒左右时间   
net.ipv4.tcp_syn_retries=2  
#net.ipv4.tcp_synack_retries=2  
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为300秒  
net.ipv4.tcp_keepalive_time=1200  
net.ipv4.tcp_orphan_retries=3  
#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间  
net.ipv4.tcp_fin_timeout=30    
#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。  
net.ipv4.tcp_max_syn_backlog = 4096  
#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭  
net.ipv4.tcp_syncookies = 1  
  
#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭  
net.ipv4.tcp_tw_reuse = 1  
#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭  
net.ipv4.tcp_tw_recycle = 1  
  
##减少超时前的探测次数   
net.ipv4.tcp_keepalive_probes=5   
##优化网络设备接收队列   
net.core.netdev_max_backlog=3000

(4) 为什么出现过多CLOSE_WAIT状态?

被动断开连接的一方(图中的B)没有关闭自身的连接,也即没有发送FIN给主动断开一方(图中的A),导致端口不能释放。

相关内容也可以参考:服务器TIME_WAIT和CLOSE_WAIT详解和解决办法

 

3、Python的socket模块:

s.send(),当对端使用(RST或者FIN)关闭了socket时,会抛出socket.error,即[Errno 10053];而当对端的TCP 接收窗口满了,则会抛出socket.timeout。 

 

4、当解决NAT打洞问题时,需要掌握:NAT的四种类型另一篇参考

一般来讲, NAT可以分为四种类型,分别是:

(1) 全锥型(Full Cone)

(2)受限锥型(Restricted Cone), 或者说是IP受限锥型

(3)端口受限锥型(Port Restricted Cone), 或者说是IP + PORT受限锥型

(4)对称型(Symmetric)

其中1,2,3属于同一种类型,都是锥型,区别只是路由器的不同的安全策略。

还有些NAT不属于这四种中的任何一种,就不在讨论范围了。

client(192.168.0.3, 100)和server(1.1.1.1, 1111)在路由器上建立好映射关系后,如果这个时候路由器(8.8.8.8)在800端口上收到从另外一台server(2.2.2.2, 2222)发来的数据,是不是应该转发给(192.168.0.3, 100)呢?

有四种情况:

(1)无条件转发给(192.168.0.3, 100), 这就是全锥型(Full Cone)NAT。
(2)如果(192.168.0.3, 100)之前给(2.2.2.2)发送过数据,则转发, 这就是受限锥型(Restricted Cone)。
(3) 如果(192.168.0.3, 100)之前给(2.2.2.2, 2222)发送过数据,则转发, 这就是端口受限锥型(Port Restricted Cone)。
(4)丢弃报文,拒绝转发, 这就是对称型NAT。

从上面也描述也可以看出,安全性系数, 对称型 > 端口受限锥型 > 受限锥型 > 全锥型

 

5、select.select(rlist, wlist, xlist[, timeout])参数相关:

“The first three arguments are sequences of ‘waitable objects’: either integers representing file descriptors or objects with a parameterless
method named fileno() returning such an integer”

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值