Есть ли способ узнать размер буфера отправки / получения для сокетов TCP?
Я пробежался как с netstat, так и с ss, а также с raw / proc / net / tcp. Там много плюсов, включая количество байтов в полете, таймеры, имя процесса и т. Д.
Но я хотел бы иметь возможность диагностировать, устанавливают ли некоторые процедуры SO_ {SND, RCV} BUF ... и, что более интересно, какие значения ядро фактически использует для каждого SKB.
Из lsof FAQ (выполните поиск по запросу «Почему lsof не сообщает о параметрах сокета»), я считаю, что Linux не делает доступной информацию, которая вам нужна. (по крайней мере, не через / proc)
Если бы это было так, вы могли бы использовать lsof -i <pid> -a -i tcp -T f
, но -T принимает только "qs", а не f в Linux. Вы можете получить дополнительную информацию из 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, чтобы выяснить, где должны работать соединения)
Вы действительно можете сделать это, используя 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
Вы можете изменить размер буфера приема и отправки следующим образом (показан буфер отправки):
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 от того, что есть на самом деле.