首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >UDP数据报套接字-对于“没有可用的缓冲区空间”,send()失败的可能原因是什么

UDP数据报套接字-对于“没有可用的缓冲区空间”,send()失败的可能原因是什么
EN

Stack Overflow用户
提问于 2020-12-12 11:21:52
回答 1查看 148关注 0票数 0

我正在测试我的代码在一个便宜的数字海洋水滴(2 2GB的内存,但我也尝试添加4 2GB的交换空间,它没有改变任何东西)。

我的程序的一部分有许多UDP客户端DGRAM套接字打开到各种本地端口(从/到127.0.0.1)。

有时,在没有发送大量数据的情况下,send()调用会失败并返回No buffer space available (错误105)。

然后,我的程序尝试使用所有其他可用套接字(对于其他本地端口),但它们都同时失败。

我将/proc/sys/net/core/wmem_max (和/proc/sys/net/core/rmem_max)设置为16MB,每个套接字的setsockopt SOL_SOCKET, SO_SNDBUF都设置为8MB。这些都不会改变任何事情。

使用No buffer space available时,send()怎么会失败?这不是应该只在我们发送()太快的时候发生吗?但这里是本地的,我不会发送太多数据。

最让我困惑的是,当进程重试任何其他套接字时,它会得到相同的错误。套接字缓冲区不是应该是完全独立的吗?

可能的原因是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-13 21:45:43

错误No buffer space available并不意味着套接字缓冲区已满。这意味着linux内核不能为套接字缓冲区分配内存。没有任何套接字缓冲区的内存,所以当这种情况发生时,在释放一些内存之前,不可能通过任何套接字发送任何数据。增加wmem_maxrmem_max可能会使问题变得更糟,因为它们可能会增加每个插槽的内存消耗。您可以检查总体内存消耗以及为udp套接字缓冲区分配了多少内存:

代码语言:javascript
复制
$ cat /proc/net/sockstat
sockets: used 315
TCP: inuse 8 orphan 0 tw 0 alloc 13 mem 1
UDP: inuse 3853 mem 240812
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0

本例中的UDP套接字每4KB使用240812页,约为940MB。有3853个打开的插座

代码语言:javascript
复制
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           1.9G        1.8G         75M        1.2M         66M         28M
Swap:            0B          0B          0B

本例中的系统具有2 GB的物理内存和非常低的空闲内存。send函数极有可能失败,并出现错误No buffer space available

如果内存实际上被套接字缓冲区消耗,那么添加交换几乎没有什么帮助,因为AFAIK缓冲区不能被交换出去。

您可以尝试使用内存更大的VM。这可能会有所帮助,或者至少可以推迟这个问题。

您还可以审核应用程序并检查套接字是如何使用的。UDP套接字缓冲区的高内存消耗可能是由应用程序中的错误或错误的设计引起的。例如,如果应用程序侦听UDP套接字,并且有数据,但应用程序不读取任何内容,则内核直到进程终止或直到应用程序调用recv时才释放内存。许多未调用recv的已打开套接字可能会耗尽内存。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65261295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档