Как сломать надстройку :: asio :: ip :: udp :: socket?

StackOverflow https://stackoverflow.com/questions/1222637

  •  10-07-2019
  •  | 
  •  

Вопрос

Я прочитал справку по asio boost, просмотрел учебник и посмотрел некоторые примеры. Тем не менее, я не могу понять, как сокрушить сокет:

<Ол>
  • Должен ли я вызвать close () или это делается деструктором сокета?
  • Когда мне следует вызывать shutdown ()
  • Каковы последствия отключения ()? Я знаю, что он "Отключает отправку или получение", но как это сделать? Что я могу ожидать, если отправлю или получу через сокет после того, как он был отключен?
  • Какие ошибки можно ожидать от close ()
  • Это было полезно?

    Решение

    Поскольку это многозадачный вопрос, я постараюсь ответить на каждую часть, чтобы вы остались довольны:

    1) Мой опыт работы с сокетами ASIO заключается в том, что деструктор обрабатывает закрытие сокета. Однако я имел дело только с TCP-сокетами. Лучший способ проверить это - просто посмотреть на код деструктора, чтобы убедиться, что он делает что-то похожее на закрытие. Я знаю, что Boost-код может быть немного сложным, поэтому проще всего создать небольшую программу-пример, которая открывает UDP-сокет и затем разрушает его. Таким образом, вы можете шагать по коду в отладчике, чтобы следовать логике.

    Поскольку разработчики Boost приняли это во внимание для сокетов TCP, мне трудно представить, что они не будут делать то же самое для сокетов UDP.

    2) Вызывайте shutdown () только тогда, когда вы чувствуете, что необходимо предотвратить выполнение кода в будущем recv и / или send розетка. Обычно это не требуется, хотя я видел, как он использовал сокеты TCP, чтобы заставить сокет отправлять RST при его закрытии (в отличие от стандартного «изящного» отключения, когда обрабатываются ожидающие отправки). ).

    3) Вы можете думать о сокетах как о двухканальной форме общения: один для чтения, другой для отправки. Вы можете выключить любой из них независимо от другого, и вы можете продолжать использовать один канал, когда другой выключен (т.е. вы все равно можете получать после выключения для отправки и наоборот). Закрытие сокета идентично вызову shutdown на recv и send.

    Выключение для recv просто препятствует тому, чтобы ваш код прочитал больше данных. Если вы попытаетесь это сделать, вы получите ошибку сокета. Аналогичным образом, если другая сторона соединения попытается отправить вам данные, она получит сообщение об ошибке (извините, что снова переключаюсь на мир TCP, но я верю, что RST получит ответ отправителю).

    Выключение для отправки также не позволяет вашему коду отправлять больше данных. Если память обслуживает меня правильно, это выглядит идентично тому, что происходит, когда вы закрываете сокет (пакет нулевой длины отправляется поперек, чтобы сообщить другой стороне, что определенный канал был закрыт). Любые будущие попытки отправить вернут ошибку.

    4) Вам нужно будет проверить свои документы, чтобы знать наверняка. MSDN даст вам довольно хорошее представление о том, хотя я не знаю, что я считаю это авторитетным.

    Другие советы

    Из примеров, приведенных на веб-сайте Boost, кажется, что вы должны просто использовать close (). Например, посмотрите на это:

    void connection::stop()
    {
      socket_.close();
    }
    

    Взято с этого адреса: HTTP-сервер

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top