Как узнать, отправил ли я UDP-пакет на открытый порт?

Я делаю программу C, в которой мне нужно проверить открытые порты UDP на целевом компьютере. Поскольку UDP не требует установления соединения, я не могу проверить возвращаемое значение connect(), как это возможно с TCP.

send() и sendto() возвращаемые значения также не помогают. На странице руководства указано:

   No  indication  of failure to deliver is implicit in a send().  Locally
   detected errors are indicated by a return value of -1.

Как я могу узнать, отправил ли я пакет UDP на открытый порт на целевом хосте?


person Marian    schedule 09.01.2011    source источник


Ответы (2)


В общем, вы не можете этого сделать.

В принципе, хост с закрытым портом должен возвращать сообщение ICMP о недоступности порта. Но они часто этого не делают; аналогичным образом отключенный или недоступный хост не будет отправлять такое сообщение. Кроме того, некоторые брандмауэры блокируют сообщение.

Снять ошибку тоже проблематично. Linux имеет четко определенную, но запутанную семантику для получения ошибок в сокетах (см. различные справочные страницы, socket(7), ip(7) и udp(7) для получения дополнительной информации). Иногда вы будете видеть предыдущую ошибку, сообщаемую, например, когда вы выполняете несвязанный sendto(). Другие ОС имеют немного отличающиеся механизмы для получения определенных ошибок сокетов.

Если на другом порту гарантированно будет конкретный протокол, вы можете отправить пакет, который должен вызвать определенный ответ (если это ваш собственный протокол, вы можете добавить тип сообщения «вы там»), тогда вы можете использовать что. Но в целом вопрос о том, генерируется ли ответ, зависит от приложения, и вы не можете отличить порт, который ничего не слушает, от порта, который слушает что-то, что решает вам не отвечать.

person MarkR    schedule 09.01.2011
comment
Извините за вопрос, но как я могу узнать, отправил ли он мне ICMP-порт-недоступен? Спасибо. - person Marian; 09.01.2011
comment
@Marian: Можете ли вы задать еще один вопрос по этому поводу? Я тоже хотел бы знать. - person Matt Joiner; 09.01.2011
comment
На самом деле я не думаю, что стоит заморачиваться с обнаружением ICMP port-unreachable, так как он может не прийти. Это особенно верно для компьютеров, на которых установлены персональные брандмауэры, которые имеют тенденцию блокировать такие полезные вещи (в основном) из-за ошибочных соображений безопасности. - person MarkR; 09.01.2011

Поскольку UDP не требует установления соединения, вам необходимо проверить состояние порта в коде вашего приложения. Например, отправить пакет на порт и дождаться ответа. Если вы не получили ответ в определенное время приложения, порт недоступен.

Конечно, вы должны разработать это как для отправляющей, так и для принимающей стороны.

person Richard Pennington    schedule 09.01.2011