Я пишу простой TCP/IP-сервер в Python между двумя клиентами и сервером. В настоящее время, когда я пытаюсь перезапустить программу сразу после ее закрытия на том же порту, оболочка сообщает мне, что порт занят.Должны ли порты быть доступны сразу после закрытия?
Я думаю, что это должно указывать на то, что каким-то образом неправильно закрывать соединение, но я не могу найти каких-либо затяжных сокетов.
Мой вопрос в том, что это предположение правильно? Я оставляю открытый сокет или это поведение в норме? Если да, есть ли у кого-нибудь советы относительно того, как я могу найти его?
На стороне сервера, я открываю два соединения и поместить их в кортеж, так что я могу цикл через них с петлей:
(self.con1, rec1) = self.s.accept()
(self.con2, rec2) = self.s.accept()
self.con = (self.con1, self.con2)
бы следующее быть достаточно код, чтобы закрыть эти соединения?
self.con1.close()
self.con2.close()
Может быть, возможно, что, возможно, помещая соединения в кортеж создает новую копию соединений, которые, возможно, вялый?
'SO_REUSEADDR' /' SO_REUSEPORT' позволяет использовать порт, который все еще находится в 'TIME_WAIT'. Чтобы избежать «TIME_WAIT» в первую очередь, вы можете использовать 'SO_LINGER', чтобы отключить затяжку при закрытии, но это не всегда работает. Другим вариантом является использование 'shutdown (SD_RECEIVE)' only, а не 'shutdown (SD_SEND)' или 'shutdown (SD_BOTH)'. Если вы сначала закрываете свой конец соединения И отправляете 'FIN', вы переходите в' TIME_WAIT'. Но вы не должны избегать «TIME_WAIT» в 99.9999999% случаев, он существует по причине защиты сессий от коррупции. –
@RemyLebeau SO_REUSEPORT для UDP, действительно для многоадресной передачи, если я правильно помню. Ничего общего с TIME_WAIT. Способ избежать TIME_WAIT - это конец, который получает первое закрытие, что является еще одним аргументом в пользу объединения пулов. 'shutdown()' на самом деле не имеет большого отношения к этому. Я никогда не пишу о SO_LINGER, так как я не верю, что кто-то никуда не должен возиться с ним. – EJP
'SO_REUSEPORT' также может использоваться для TCP. Он позволяет нескольким потокам/процессам прослушивать один и тот же порт, каждый из которых вызывает 'accept()'. Новый клиент может быть принят любым из них. Полезно для объединения и балансировки нагрузки. Что касается 'TIME_WAIT', вы вводите его только в том случае, если вы первый участник, отправляющий' FIN'. Нет 'FIN' no' TIME_WAIT'. Конечно, пропуская 'FIN' не нравится другой стороне. –