can't bind local address: Address already in use
Тогда пробуем использовать параметр SO_REUSEPORT
macosx % sock -u -s 8888 &
[1] 17612
macosx % sock -u -s -T 8888
can't bind local address: Address already in use
Наконец, задаем параметр SO_REUSEPORT
macosx % sock -u -s -Т 9999 &
[1] 17614
macosx % sock -u -s -T 9999 &
[2] 17615
macosx % netstat -na | grep 9999
udp4 0 0 *.9999 *.*
udp4 0 0 *.9999 *.*
7.7. Этот параметр (-d
ping
использует ICMP-сокет, а параметр сокета SO_DEBUG
влияет только на TCP-сокеты. Описание параметра сокета SO_DEBUG
всегда было довольно расплывчатым, наподобие «этот параметр допускает отладку на соответствующем уровне протокола», и единственный уровень протокола, где реализуется данный параметр — это TCP.7.8. Временная диаграмма приведена на рис. Д.4.
Рис. Д.4
. Взаимодействие алгоритма Нагла с задержанными сегментами ACK7.9. Установка параметра сокета TCP_NODELAY
write
, даже если имеется еще один небольшой пакет, ожидающий отправки. Это показано на рис. Д.5. Полное время в данном примере превышает 150 мс.Рис Д.5
. Предотвращение алгоритма Нагла путем установки параметра TCP_NODELAY7.10. Как показано на рис. Д.6, преимущество данного решения состоит в уменьшении числа пакетов.
Рис. Д.6
. Использование функции writev вместо параметра сокета TCP_NODELAY7.11. В разделе 4.2.3.2 говорится: «задержка ДОЛЖНА быть меньше 0,5 с, а в потоке полноразмерных сегментов СЛЕДУЕТ использовать сегмент ACK по крайней мере для каждого второго сегмента». Беркли-реализации задерживают сегмент ACK не более, чем на 200 мс [128, с. 821].
7.12. Родительский процесс сервера в листинге 5.1 большую часть времени блокирован в вызове функции accept
read
, который содержится в функции readline
. Проверка работоспособности с помощью параметра SO_KEEPALIVE
не влияет на прослушиваемый сокет, поэтому в случае, если клиентский узел выйдет из строя, родительский процесс не пострадает. Функция read дочернего процесса возвратит ошибку ETIMEDOUT
примерно через 2 ч после последнего обмена данными через соединение.7.13. Клиент, приведенный в листинге 5.4, большую часть времени блокирован вызовом функции fgets
ETIMEDOUT
. Но клиент блокирован вызовом функции fgets
, поэтому он не увидит этой ошибки, пока не осуществит чтение или запись на сокете. Это одна из причин, по которой в главе 6 листинг 5.4 был изменен таким образом, чтобы использовать функцию select
.7.14. Этот клиент большую часть времени блокирован вызовом функции select
ETIMEDOUT
(как показано в предыдущем решении).7.15. Происходит обмен только двумя сегментами, а не четырьмя. Вероятность того, что таймеры двух систем будут строго синхронизированы, очень мала, следовательно, на одном конце соединения таймер проверки работоспособности сработает немного раньше, чем на другом. Первый из сработавших таймеров посылает проверочное сообщение, заставляя другой конец послать в ответ сегмент ACK. Но получение проверочного сообщения приводит к тому, что таймеру проверки работоспособности с более медленными часами будет присвоено новое значение — он сдвинется на 2 ч вперед.
7.16 Изначально в API сокетов не было функции listen
socket
содержал параметр сокета, а параметр SO_ACCEPTCONN
использовался для задания прослушиваемого сокета. Когда добавилась функция listen
, флаг остался, но теперь его может устанавливать только ядро [128, с. 456].Глава 8
8.1. Да. Функция read
recvfrom
возвращает 2048 байт (первую из двух дейтаграмм). Функция recvfrom
на сокете дейтаграмм никогда не возвращает больше одной дейтаграммы, независимо от того, сколько приложение запрашивает.