我试图确定unix数据报套接字的不同限制,因为我将其用作我的项目的IPC。 我想控制的晦涩之处是套接字内部缓冲区的大小: 我想知道在套接字阻塞之前可以发送多少个数据报。
我了解2个不同的限制会影响套接字缓冲区的大小:
-
/proc/sys/net/core/wmem_{max,default}
设置套接字的写缓冲区的最大(默认)大小 -
/proc/sys/net/unix/max_dgram_qlen
设置缓冲区可以容纳的最大数据报数
我知道/proc/sys/net/core/rmem_{max,default}
设置套接字读取缓冲区的最大(默认)大小,但是当我在本地unix套接字上工作时,似乎没有影响。
我已将wmem_{max,default}
设置为136314880(130 MB),并将max_dgram_qlen
设置为500000。
并编写了一个小程序,其中发送方套接字仅将固定大小的数据报发送到接收方套接字,直到被阻塞为止,然后我打印能够发送的数据报的大小和数量。
这是我使用的代码:
#include <err.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
/* Payload size in bytes. */
#define PAYLOAD_SIZE 100
#define CALL_AND_CHECK(syscall) \
if (syscall < 0) { err(1,NULL); }
int main(void)
{
int receiver_socket_fd = socket(AF_UNIX,SOCK_DGRAM | SOCK_NONBLOCK,0);
if (receiver_socket_fd < 0)
err(1,NULL);
char* binding_path = "test_socket";
struct sockaddr_un addr;
memset(&addr,sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path,binding_path,sizeof(addr.sun_path));
/* Check if the file exists,if yes delete it ! */
if (access(binding_path,F_OK) != -1) {
CALL_AND_CHECK(unlink(binding_path));
}
CALL_AND_CHECK(bind(receiver_socket_fd,(struct sockaddr const*) &addr,sizeof(addr)));
int sender_socket_fd = socket(AF_UNIX,0);
if (sender_socket_fd < 0)
err(1,NULL);
CALL_AND_CHECK(connect(sender_socket_fd,sizeof(addr)));
struct payload { char data[PAYLOAD_SIZE]; };
/* Create test payload with null bytes. */
struct payload test_payload;
memset(&test_payload.data,PAYLOAD_SIZE);
ssize_t total_size_written = 0;
ssize_t size_written = 0;
do {
size_written = write(sender_socket_fd,(const void *) &test_payload,PAYLOAD_SIZE);
if (size_written > 0)
total_size_written += size_written;
} while (size_written > 0);
printf("socket_test: %zu bytes (%ld datagrams) were written before blocking,last error was :\n",total_size_written,total_size_written / PAYLOAD_SIZE);
perror(NULL);
CALL_AND_CHECK(unlink(binding_path));
CALL_AND_CHECK(close(sender_socket_fd));
CALL_AND_CHECK(close(receiver_socket_fd));
return 0;
}
我期望达到套接字的最大字节数(此处为130MB)或我设置的最大数据报数(500 000)。
但是实际结果是,我只能在被阻止之前写 177494数据报。
我可以更改有效负载的大小,这始终是相同的结果(只要我没有先达到最大大小(以字节为单位))。因此,看来我超出了我无法找到的 max_dgram_qlen和wmem_ {max,default} 的极限。
我当然尝试调查ulimit
或limits.conf
而不成功。 ulimit -b
甚至无法在我的机器上运行(说“找不到选项”并返回)。
我正在使用Debian 10(破坏程序),但是已经在不同的OS上启动了测试程序,结果是:我达到了我不知道的数据报限制。
您是否知道我未达到并达到哪个限制?如果我可以阅读或修改此限制?