knetstat — это простой модуль ядра Linux, который добавляет в /proc/net
четыре новых файла: tcpstat
, tcp6stat
, udpstat
и udp6stat
. Содержимое этих файлов примерно эквивалентно выводам команды netstat
с параметрами -t4an
, -t6an
, -u4an
и -u6an
соответственно, т.е. они предоставляют информацию о сокетах TCP и UDP в удобочитаемой форме. Разница с соответствующим выводом netstat
заключается в том, что у них есть дополнительный столбец, в котором отображаются (подмножество) параметры сокета. Это было основной мотивацией для написания модуля ядра knetstat: в настоящее время в Linux у администратора нет возможности проверять параметры, установленные для сокета, созданного каким-либо процессом (кроме использования strace
или эквивалентного инструмента для этого процесса при создании сокета). /время конфигурации), поскольку эта информация не передается через файловую систему /proc
.
knetstat внутренне повторно использует инфраструктуру, используемую ядром, для генерации содержимого файлов /proc/net/tcp
, /proc/net/tcp6
, /proc/net/udp
и /proc/net/udp6
. Это означает, что между записями в этих файлах и записями в файлах, созданных knetstat, существует взаимно однозначное соответствие. Между ними различается только форматирование и информационное наполнение.
Вот пример вывода:
$ cat /proc/net/tcpstat
Recv-Q Send-Q Local Address Foreign Address Stat Diag Options
0 0 127.0.0.1:6010 0.0.0.0:* LSTN SO_REUSEADDR=1,SO_KEEPALIVE=0,TCP_NODELAY=0
0 0 0.0.0.0:22 0.0.0.0:* LSTN SO_REUSEADDR=1,SO_KEEPALIVE=0,TCP_NODELAY=0
0 0 192.168.1.18:22 192.168.1.6:49537 ESTB SO_REUSEADDR=1,SO_KEEPALIVE=1,TCP_NODELAY=1
0 0 127.0.0.1:6010 127.0.0.1:45462 ESTB SO_REUSEADDR=1,SO_KEEPALIVE=0,TCP_NODELAY=1
0 0 127.0.0.1:45462 127.0.0.1:6010 ESTB SO_REUSEADDR=0,SO_KEEPALIVE=1,TCP_NODELAY=1
В столбце «Диагностика» могут отображаться следующие диагностические показатели:
Индикатор | Значение |
---|---|
>| | Окно отправителя (т. е. окно, объявленное удаленной конечной точкой) равно 0. Никакие данные не могут быть отправлены партнеру. |
|< | Окно получателя (т. е. окно, объявленное локальной конечной точкой) равно 0. Никакие данные не могут быть получены от узла. |
># | Имеются неподтвержденные пакеты, и последнее подтверждение было получено более секунды назад. Это может указывать на проблемы в сети или на сбой узла. |
SO_REUSEADDR
, SO_REUSEPORT
, SO_KEEPALIVE
(TCP), TCP_KEEPIDLE
(TCP), TCP_KEEPCNT
(TCP), TCP_KEEPINTVL
(TCP), SO_RCVBUF
, SO_SNDBUF
, SO_RCVTIMEO
, SO_SNDTIMEO
, SO_LINGER
(TCP), TCP_NODELAY
, TCP_FASTOPEN
, TCP_DEFER_ACCEPT
, SO_BROADCAST
(UDP) TCP_KEEPIDLE, TCP_KEEPCNT и TCP_KEEPINTVL соответствуют значениям tcp_keepalive_time, tcp_keepalive_probes и tcp_keepalive_intvl, описанным в tcp(7) и соответствующих sysctls. Если эти значения переопределены на уровне сокета (установив для них значение, отличное от нуля), они будут напечатаны knetstat, в противном случае ядро будет использовать sysctls, и модуль будет игнорировать их при печати вывода.
Текущий код knetstat был успешно протестирован с версиями ядра 3.13, 3.18, 4.4, 4.8, 4.9 и 4.15. Это может работать и с другими версиями.
Чтобы собрать модуль, убедитесь, что у вас есть заголовки для работающего в данный момент ядра, а также базовые инструменты сборки, такие как make и GCC. Например, в Ubuntu:
# apt-get install linux-headers-$(uname -r) make gcc
Затем проверьте исходный код knetstat и выполните make
. Это должно создать knetstat.ko
, который можно загрузить с помощью insmod
.
В следующей таблице показано соответствие между параметрами сокета, сообщаемыми knetstat, и методами установки, определенными классом java.net.Socket
. Эту информацию можно использовать для определения конфигурации, которую процесс Java применил к экземпляру java.net.Socket
на основе выходных данных knetstat. Сопоставление простое, за исключением setSoTimeout
.
Java-метод | Опция сокета, о которой сообщает knetstat |
---|---|
setKeepAlive | SO_KEEPALIVE |
setReceiveBufferSize | SO_RCVBUF |
setReuseAddress | SO_REUSEADDR |
setSendBufferSize | SO_SNDBUF |
setSoLinger | SO_LINGER |
setSoTimeout | никто [*] |
setTcpNoDelay | TCP_NODELAY |
[*] В отличие от того, что предлагает Javadoc, метод setSoTimeout
фактически не устанавливает никаких параметров сокета в Linux. По умолчанию экземпляры java.net.Socket
поддерживаются java.net.SocksSocketImpl
(даже если прокси-сервер SOCKS не настроен). Этот класс расширяет java.net.AbstractPlainSocketImpl
, который сохраняет время ожидания внутри для последующего использования методами чтения в java.net.SocketInputStream
. Они, в свою очередь, передают тайм-аут вызову системного вызова poll
, который ожидает, пока данные не станут доступны для чтения (или не произойдет ошибка).