有没有办法查找 TCP 套接字的发送/接收缓冲区大小?
我仔细研究了 netstat 和 ss,以及原始的 /proc/net/tcp。那里有很多有用的东西,包括传输字节数、计时器、进程名称等。
但我希望能够诊断某些进程是否正在设置 SO_{SND,RCV}BUF……以及更有趣的是内核对每个 SKB 实际上使用了什么值。
答案1
来自lsof 常见问题解答(搜索“为什么 lsof 不报告套接字选项”),我相信 Linux 不会提供您所需的信息。(至少不是通过 /proc)
如果是,您可以使用lsof -i <pid> -a -i tcp -T f
,但 -T 只接受“qs”,而不是 Linux 上的 f。您可以从 netstat ( netstat --tcp -p -o -e -e -v | grep <pid>
) 获取一些其他信息,其中包括发送队列和接收队列以及一些计时器信息。
你可以使用 strace。你必须通过 strace ( strace -ff -e network,ioctl PROGRAM
) 运行程序,或者在它设置 TCP 套接字 ( strace -fff -e network,ioctl -p PID
) 之前运行程序。 ioctl
这些选项是如何设置的,network
应该能够捕获足够的信息来判断这些连接是什么。(但只需 ioctl,然后使用 lsof 来确定连接应该在哪里工作)
答案2
您实际上可以使用 来做到这一点https://github.com/veithen/knetstat
。
例如nc -I 8192 -O 8192 www.google.com 80
这将给出(参见第三行的SO_RCVBUF
和):SO_SNDBUF
$ cat /proc/net/tcpstat
Recv-Q Send-Q Local Address Foreign Address Stat Diag Options
0 0 0.0.0.0:22 0.0.0.0:* LSTN SO_REUSEADDR=1,SO_REUSEPORT=0,SO_KEEPALIVE=0,TCP_NODELAY=0
0 0 10.132.0.4:22 74.125.73.164:38922 ESTB SO_REUSEADDR=1,SO_REUSEPORT=0,SO_KEEPALIVE=1,TCP_NODELAY=1
0 0 10.132.0.4:44058 74.125.206.103:80 ESTB SO_REUSEADDR=0,SO_REUSEPORT=0,SO_KEEPALIVE=0,SO_RCVBUF=8192,SO_SNDBUF=8192,TCP_NODELAY=0
0 0 10.132.0.4:44054 74.125.206.103:80 TIMW
0 0 10.132.0.4:22 74.125.73.96:45722 ESTB SO_REUSEADDR=1,SO_REUSEPORT=0,SO_KEEPALIVE=1,TCP_NODELAY=1
答案3
您可以按如下方式更改接收和发送缓冲区的大小(显示发送缓冲区):
int buffersize = 64*1024; // 64k
setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *) &buffersize, sizeof(buffersize));
要获取当前大小,请使用:
socklen_t buffersize_len = sizeof(buffersize); // in/out parameter
getsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *) &buffersize, &buffersize_len);
Linux 中有一个已知错误,它会将当前缓冲区大小报告为设置值的 1/2。我不记得内部值是否是请求值的 1/2,或者报告是否是实际值的 1/2。