Сторона, которая инициировала закрытие соединения, является той, которая заканчивается в состоянии TIME_WAIT
. read()
Возврат 0 должен указывать, что сервер сначала закрыл сокет, поэтому да - это должно означать, что TIME_WAIT
заканчивается на стороне сервера, а клиент проходит через LAST_ACK
.
В конце дня вы не можете избежать состояния TIME_WAIT
. Даже если вам удастся перенести его с клиента на сервер, вы все равно не сможете повторно использовать этот кортеж (server host, server port, client host, client port)
до тех пор, пока не закончится TIME_WAIT
(независимо от того, на какой стороне он включен).
Поскольку три части этого кортежа фиксируются в вашем сценарии (server host
, server port
, client host
), вы на самом деле есть только эти варианты:
Попробуйте сделать несколько клиентских портов. Некоторые операционные системы используют только небольшой диапазон доступных портов для «эфемерных портов» по умолчанию (я не уверен в OSX в этом отношении). Если это так, посмотрите, можете ли вы изменить диапазон с настройкой конфигурации в ОС или, альтернативно, запустить приложение для рабочего порта с bind()
/connect()
в цикле до тех пор, пока соединение не будет работать.
Развернуть число доступных client host
значений, используя несколько IP-адресов на вашем клиенте. Однако вам нужно иметь приложение bind()
на один из этих IP-адресов.
Расширение количества доступных server host
/server port
значений с использованием нескольких портов и/или IP-адресов на сервере. Клиенту нужно будет выбрать один для подключения (циклический, случайный и т. Д.).
Возможно, лучший вариант, если это выполнимо: отредактируйте свой протокол, чтобы завершившиеся соединения не были закрыты, но переходите в «незанятое» состояние, чтобы их можно было повторно использовать позже, вместо того чтобы открывать новое соединение (например, HTTP keep-alive).
Sidenote: значение ERRNO неопределен при считывании возвращает 0 - ERRNO определяется только после сбоя. –