Сторона, которая инициировала закрытие соединения, - это сторона, которая оказывается в состоянии 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).