Какова семантика получения EADDRINUSE, когда прослушивающий сокет не привязан, но соединения открыты?

Какова семантика получения EADDRINUSE, когда прослушивающий сокет не привязан, но соединения открыты?

Рассмотрим родительский процесс, который завершает 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что затрудняет понимание ответа.

Связанный контент