Назад | Перейти на главную страницу

Зачем клиенту отправлять пакет RST в ответ на SYN, ACK?

У меня есть веб-сервис HTTP, где иногда установка соединения не работает странным образом:

В каких ситуациях клиентская система может решить ответить пакетом RST? Я мог представить, что это происходит, когда SYN, ACK содержит, например. неправильные порядковые номера (но, похоже, это не применимо в моем случае - порядковые номера выглядят нормально). Поэтому меня интересует исчерпывающий :-) список случаев, когда клиент отправляет пакет RST после получения пакета SYN, ACK.

В частности, возможно ли, чтобы код клиентского приложения (с использованием обычного API сокетов в стиле BSD под Linux) вызвал этот пакет RST, например. позвонив close() пока продолжается трехстороннее рукопожатие?

В заключение: проблема была в тупой ошибке в моем коде (в клиенте).

Клиент в этом случае использует неблокирующие сокеты, поэтому connect() вызов вернется немедленно, пока ядро ​​продолжает ждать пакета SYN, ACK от сервера. К сожалению, код клиента был очень нетерпеливым: если соединение не было установлено через несколько сотен миллисекунд, клиент звонил close() на розетке.

В некоторых редких случаях SYN, ACK-пакеты от сервера будут задерживаться на несколько сотен миллисекунд на своем пути по сети. Когда отложенный ответ наконец прибыл на клиентский хост, ядро ​​увидит, что сокет уже закрыт, и будет рассматривать ответ SYN, ACK как принадлежащий недопустимому сокету. Вот почему он ответил бы на сервер пакетом RST.

Итак, да, код приложения (с использованием обычного API сокетов в стиле BSD под Linux) может вызвать этот пакет RST: используя неблокирующий сокет и закрывая соединение, пока трехстороннее рукопожатие все еще продолжается.