是否可以在 TCP 中修改内核结构的单个成员?我希望能够使用 setsockopt()
来更新 TCP 中 tcp_info 结构的成员。
我试过以下方法:
struct tcp_info info;
unsigned int optlen = sizeof(struct tcp_info);
if (getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, &optlen) < 0)
printf("Can't get data from getsockopt.\n");
info.retransmits += 10; // random member of tcp_info - as example
if (setsockopt(sock, IPPROTO_TCP, TCP_INFO, (char *) &info, optlen) < 0)
printf("Can't set data with setsockopt.\n");
setsockopt()
调用失败(返回负值)。
我尝试解决它的方式(如上),鉴于它已经奏效 - 似乎不是最优的。是否可以修改结构中的成员值,而不必获取和更新整个结构(其所有成员)?
最佳答案
您不能使用 setsockopt()
设置任意值。它有一个有限的选项列表,您可以设置。
我将在本示例中使用 FreeBSD 内核,但所有这些在 Linux 中即使不完全相同,也是相似的。我将跳转到 sys/kern/uipc_socket.c
中的 FreBSD 的 sosetopt()
函数.
您可以设置的唯一有效选项是:
SO_ACCEPTFILTER, SO_LINGER, SO_DEBUG, SO_KEEPALIVE, SO_DONTROUTE, SO_USELOOPBACK, SO_BROADCAST, SO_REUSEADDR, SO_REUSEPORT, SO_REUSEPORT_LB, SO_OOBINLINE, SO_TIMESTAMP, SO_BINTIME, SO_NOSIGPIPE, SO_NO_DDP, SO_NO_OFFLOAD, SO_RERROR, SO_SETFIB, SO_USER_COOKIE, SO_SNDBUF, SO_RCVBUF, SO_SNDLOWAT, SO_RCVLOWAT, SO_SNDTIMEO, SO_RCVTIMEO, SO_LABEL, SO_TS_CLOCK, and SO_MAX_PACING_RATE.
该列表包含许多状态标志,启用或禁用功能。只有少数允许设置数值。
- SO_USER_COOKIE - 将用户指定的元数据值设置为套接字。
- SO_SNDBUF/SO_RCVBUF - 设置为发送和接收分配的缓冲区大小。
- SO_SNDLOWAT/SO_RCVLOWAT - 设置每次调用发送/接收的最小数据量。
- SO_SNDTIMEO/SO_RCVTIMEO - 设置发送/接收调用的超时时间。
- SO_MAX_PACING_RATE - 指示网络适配器限制传输速率。
这些都没有将值直接写入内核结构。要完成您要求的那种事情,您将需要修改内核。你的other question addresses那个目标。
关于linux - 使用 setsockopt() 修改 TCP 中的内核结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44253820/