gpt4 book ai didi

python - 可以存储在套接字缓冲区中的最大 UDP 数据包数? (Ubuntu)

转载 作者:可可西里 更新时间:2023-11-01 10:32:01 26 4
gpt4 key购买 nike

客户:

import socket
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
msg = b"X"
for i in range(1500):
s.sendto(msg,("<IP>",<PORT>))

服务器:

import socket
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(("",>PORT>))
counter = 0
for i in range(1500):
s.recv(1)
counter += 1

我有两台机器 - 第一台装有 Windows7,第二台装有 Ubuntu 16.04。

现在的问题:

如果我尝试从客户端向服务器发送 1500 个 UDP 数据包(例如),则:

  • Windows7 为客户端,Ubuntu16.04 为服务器:服务器只接收 200 到 280 个数据包

  • Ubuntu16.04为客户端,Windows7为服务器:服务器收到所有 1500 个数据包

我的第一个问题:

这是什么原因?操作系统有什么限制吗?

第二个问题:

是否可以在 Python 中优化套接字?

我知道 UDP 数据包可能会丢失 - 但最多占所有数据包的 4/5?

编辑:为什么会有这样的问题?想象一下,我有一个大型传感器网络……和一台服务器。每个传感器节点都应将其信息发送到服务器。服务器上的程序只能以异步方式编程——服务器只能在特定时间从套接字中读取数据。现在我想计算在服务器无法读出其缓冲区的时间段内有多少传感器节点可以通过 UDP 数据包将数据发送到服务器。有了缓冲区中可以存储多少个不同的 UDP 数据包的信息,我就可以计算出我可以使用多少个传感器节点...

最佳答案

与其编写困惑的评论记录,不如花几分钱解决这个问题。正如 redhat 所记录的那样在撰写本文时,不同操作系统的默认值是:

  • Linux:131071
  • Windows:无已知限制
  • Solaris:262144
  • FreeBSD, Darwin :262144
  • AIX:1048576

这些值应该对应于输出:

import socket
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
print(s.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF))

这些数字表示在任何给定时刻套接字接收缓冲区中可以容纳多少字节。这些数字可以在任何给定时间增加,代价是为此缓冲区保留 RAM(或者至少我记得是这样)。

在 Linux(和一些 BSD 风格)上,要增加缓冲区,您可以使用 sysctl:

sudo sysctl -w net.core.rmem_max=425984
sudo sysctl -w net.core.rmem_default=425984

这会将缓冲区设置为 416KB。如果您经常看到缓冲,您很可能会将其增加到几兆字节。

但是,缓冲区通常表示有问题,因为您的机器应该很少有缓冲区。它是一种处理突如其来的峰值并充当机器存储工作负载的小盘子的机制。如果它满了,要么你有一个非常慢的代码需要变得更快,要么你需要卸载你的服务器很多。因为如果缓冲区填满 - 无论它有多大,最终它都会再次变满。

据说您还可以通过以下方式增加 Python 的缓冲区大小:

s.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF, 1024)

但是,同样,如果您的操作系统被限制在某个屋顶 - 这将取代您在 python 程序中放置的任何值。

tl;博士:

每个操作系统都有基于优化/性能原因的限制。套接字、文件句柄(基本上任何 I/O 操作)都有它们。

很常见,你应该能找到很多关于它的资料。以上所有这些信息主要是通过搜索“linux udp recieve buffer”找到的。

此外,“windows 增加 udp 缓冲区大小”让我想到了这个:Change default socket buffer size under Windows

最后的说明

正如您所提到的,由于您使用的是 UDP,性能、数量等可能会有很大差异。它很容易因速度而丢失数据。服务器、驱动程序、NIC(特别重要,某些 NIC 的硬件缓冲区有限,可能会导致这些问题)等之间的距离都会影响您将接收的数据。在这些情况下,Windows 也会执行很多自动操作,确保将 Linux 机器调整为相同的参数。 UDP 数据包不仅包含您发送的数据量..还包含其前面的 header 中的所有参数(在 IP 数据包中,例如 TTL、分段、ECN 等)。

例如,您可以调整 UDP 堆栈在特定负载下可以占用多少内存,以找出您的下限阈值(UDP 不会费心检查 RAM 使用情况)、压力阈值(负载下的内存管理)和最大值UDP 套接字可以使用每个套接字。

sudo sysctl net.ipv4.udp_mem

这是一篇来自 ESnet 的关于 UDP 调优的好文章:

除此之外,您正在调整自己的坟墓。最有可能的是,您的问题可以通过重新设计代码来解决。因为除非您实际上从您的网络中插入 1-10GB/s,否则内核应该能够处理它,假设您处理数据包的速度足够快,而不是将它们堆积在缓冲区中。

关于python - 可以存储在套接字缓冲区中的最大 UDP 数据包数? (Ubuntu),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51245457/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com