SO_RCVBUF大小如何与传入数据包大小相关?
将套接字接收缓冲区设置为指定的字节数是否与可以存储的消息大小直接相关 示例:SO_RCVBUF大小如何与传入数据包大小相关?,c,linux,sockets,networking,berkeley-sockets,C,Linux,Sockets,Networking,Berkeley Sockets,将套接字接收缓冲区设置为指定的字节数是否与可以存储的消息大小直接相关 示例: 如果100字节消息通过UDP连续发送到设置为4000字节的套接字缓冲区,我能期望缓冲区能够容纳40消息吗 我认为设置缓冲区大小,如下所示: int size = 4000; setsockopt(id, SOL_SOCKET, SO_RCVBUF, (char *)&size, sizeof(size)); 让缓冲区从传入的数据包中填充,将产生一个包含40条消息的缓冲区 关闭UDP发送器并处理缓冲区后,我
如果
100
字节消息通过UDP连续发送到设置为4000
字节的套接字缓冲区,我能期望缓冲区能够容纳40
消息吗
我认为设置缓冲区大小,如下所示:
int size = 4000;
setsockopt(id, SOL_SOCKET, SO_RCVBUF, (char *)&size, sizeof(size));
让缓冲区从传入的数据包中填充,将产生一个包含40条消息的缓冲区
关闭UDP发送器并处理缓冲区后,我观察到的情况并非如此。尽管我的消息是
100
字节,但似乎4000
字节缓冲区只能容纳大约4
条消息
100
字节消息如何占用缓冲区中的1000
字节?这有意义吗?这是什么原因造成的,我如何根据可以容纳多少条消息来计算缓冲区大小
编辑:不能解决我的问题。
那里的用户没有正确调用
setsockopt
。我试图找到描述套接字接收缓冲区与实际可容纳的大小消息数量之间关系的文档。您需要阅读所使用API的文档。它清楚地表明系统可以调整实际缓冲区大小,并且您应该调用
getsockopt()
来确定实际缓冲区大小。还请记住,系统必须将UDP报头和有效负载存储在某个位置。@EJPgetsockopt()
返回与设置相同的值。即使消息是100字节,并且getsockopt()
返回4000,它也只能容纳4条消息。如果我将接收缓冲区设置为8000,它可以容纳8条消息。我只是不知道发生了什么。为什么它需要为100字节的消息分配额外的900字节。这是正常的行为吗?也许这与对齐有关?不管消息大小如何,它可能为每个数据报分配1000字节。关于这些函数的linux文档没有讨论这个问题。您确定消息是100字节吗?您在Wireshark中看到了什么?@dbush Wireshark显示消息负载的100个字节(与recv()返回的字节数相同)。Wireshark还显示了导线上的142个原始字节。所以我假设头是42个字节。我见过的最小套接字缓冲区大小在一些旧的Windows版本上是8k,即使在20年前也总是太小了。大约在1983年,在BSD4.2中有一篇论文详细介绍了一项重大的吞吐量改进,将其从1k更改为4k。在90年代早期,OS/2的容量是28k,在我十年多前写书的时候,大多数Unix和Linuxes的容量都是48k左右。人们现在使用兆字节。在我看来,你已经有了你需要的所有证据。另一个24k肯定不会杀死任何人?你需要阅读你正在使用的API的文档。它清楚地表明系统可以调整实际缓冲区大小,并且您应该调用getsockopt()
来确定实际缓冲区大小。还请记住,系统必须将UDP报头和有效负载存储在某个位置。@EJPgetsockopt()
返回与设置相同的值。即使消息是100字节,并且getsockopt()
返回4000,它也只能容纳4条消息。如果我将接收缓冲区设置为8000,它可以容纳8条消息。我只是不知道发生了什么。为什么它需要为100字节的消息分配额外的900字节。这是正常的行为吗?也许这与对齐有关?不管消息大小如何,它可能为每个数据报分配1000字节。关于这些函数的linux文档没有讨论这个问题。您确定消息是100字节吗?您在Wireshark中看到了什么?@dbush Wireshark显示消息负载的100个字节(与recv()返回的字节数相同)。Wireshark还显示了导线上的142个原始字节。所以我假设头是42个字节。我见过的最小套接字缓冲区大小在一些旧的Windows版本上是8k,即使在20年前也总是太小了。大约在1983年,在BSD4.2中有一篇论文详细介绍了一项重大的吞吐量改进,将其从1k更改为4k。在90年代早期,OS/2的容量是28k,在我十年多前写书的时候,大多数Unix和Linuxes的容量都是48k左右。人们现在使用兆字节。在我看来,你已经有了你需要的所有证据。再加上24k肯定杀不了人?