我正在尝试将默认套接字发送缓冲区大小更改为较小的大小,以查看 UDP 吞吐量如何影响小型 UDP 数据报。为此,我将setsockopt
函数与选项一起使用,SO_SNDBUF
并尝试将缓冲区大小设置为 64 字节。我也getsockopt
用来查看setsockopt
函数的结果。
这是我使用的代码:
int sock_fd;
struct sockaddr_in server_addr;
static int target_port = PORT;
int curr_snd_buff = 0;
int sk_snd_buff = 64;
socklen_t optlen;
if( (sock_fd=socket(AF_INET,SOCK_DGRAM,0)) == -1)
fatal("in socket (client_udp)");
memset(&server_addr, 0, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr=inet_addr(args->a_ip);
server_addr.sin_port=htons(target_port);
if ( sk_snd_buff > 0 ) >{
optlen = sizeof(sk_snd_buff);
// get the default socketh send buffer size
if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &curr_snd_buff, &optlen) == -1) {
fatal("getting the socket send buffer");
}
printf("* default socket send buffer: %d\n", curr_snd_buff);
printf("* attempting to change it to: %d\n", sk_snd_buff);
if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &sk_snd_buff, optlen) == -1) {
fatal("changing the socket send buffer");
}
if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &curr_snd_buff, &optlen) == -1) {
fatal("getting the socket send buffer");
}
printf("* new socket send buffer: %d\n", curr_snd_buff);
}
但是,我看到的是,每次尝试设置一个较小的值时,缓冲区大小的下限都设置为 4608 字节。以下是上述代码的输出:
- 默认套接字发送缓冲区:212992
- 试图将其更改为:2304
- 新的套接字发送缓冲区:4608
通过尝试各种尺寸,我发现尺寸 <= 2304 会发生这种情况。对于更大的尺寸,例如 2305,我会得到更大的尺寸:
- 默认套接字发送缓冲区:212992
- 试图将其更改为:2305
- 新的套接字发送缓冲区:4610
对于一些更大的尺寸,例如 3000,是我要求的尺寸的两倍:
- 默认套接字发送缓冲区:212992
- 试图将其更改为:3000
- 新的套接字发送缓冲区:6000
通过网上搜索,我发现Linux在设置内核时会将其值加倍,并在查询时返回加倍的值: Understanding set/getsockopt SO_SNDBUF
有没有办法减少套接字发送缓冲区大小的最小下限?例如,将其设置为 64 字节?