Рассмотрим родительский процесс, который завершает socket/bind/accept
, и будет разветвлять дочерние процессы с этим сокетом, открытым для связи с ними, в то время как родительский процесс продолжает принимать соединения. Затем этот родительский процесс завершается.
Другой процесс теперь пытается привязаться к тому же адресу, к которому был привязан родительский процесс, на том же порту, но получает ошибку EADDRINUSE.
Однако, когда вы завершаете этот процесс с помощью sshd
, кажется,sshd
являетсяможет повторно подключиться к закрытому порту, в то время как во время окна перезагрузки (когда родительский процесс sshd не запущен) другая программа (запущенная от имени другого пользователя) просто получает EADDRINUSE.
Какая семантика за этим стоит? Почему можно sshd
перепривязать, а процесс другого пользователя нет?
Кроме того, я могу подтвердить, что netstat -a | grep PORT
вывод из того времени, когда работает только дочерний процесс (когда другой процесс не может bind
), единственным соединением является одно ESTABLISHED
, в LISTEN
состоянии none.
решение1
Хотя я не понимаю всей семантики (либо ищу не там, либо документации не хватает), я считаю, что в течение определенного времени после закрытия соединения (возможно, установленного параметром SO_LINGER
), ни один процесс не может открыть новый сокет с теми же данными, если они не установлены SO_REUSEADDR
.
Насколько я понимаю, это делается для того, чтобы предотвратить повторное подключение через секунду после разрыва соединения и предотвратить необходимость обработки пакетов, предназначенных для предыдущего процесса.
man 7 socket
не документирует это как часть, SO_REUSEADDR
что затрудняет понимание ответа.