работа в сети — странное поведение netcat с UDP

Я заметил странное поведение при работе с netcat и UDP. Я запускаю экземпляр (экземпляр 1) netcat, который прослушивает порт UDP:

nc -lu -p 10000

Поэтому я запускаю еще один экземпляр netcat (экземпляр 2) и пытаюсь отправить дейтаграммы моему процессу:

nc -u 127.0.0.1 10000

Я вижу дейтаграммы. Но если я закрываю экземпляр 2 и снова запускаю netcat (экземпляр 3):

nc -u 127.0.0.1 10000

Я не вижу дейтаграмм на терминале экземпляра 1. Очевидно, что операционная система назначает другой порт-источник UDP в экземпляре 3 относительно экземпляра 2, и проблема заключается в следующем: если я использую тот же порт источника экземпляра 2 (пример 50000):

 nc -u -p 50000 127.0.0.1 10000

снова экземпляр 1 netcat получает дейтаграммы. UDP — это протокол без установления соединения, так почему? Это стандартное поведение netcat?

32

Решение

когда nc прослушивает сокет UDP, он «блокирует» порт источника и IP-адрес первого полученного пакета. Проверьте этот след:

socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(10000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
recvfrom(3, "f\n", 2048, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, [16]) = 2
connect(3, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, 16) = 0

Здесь вы можете видеть, что он создал сокет UDP, настроил его для повторного использования адреса и привязал его к порту 10 000. Как только он получил свою первую дейтаграмму (из порта 52 832), он выпустил connect системный вызов, «соединяющий» его с 127.0.0.1:52,832. Для UDP connect отклоняет все пакеты, которые не соответствуют IP-адресу и порту в connect,

40

Другие решения

Использовать -k опция:

nc -l -u -k 0.0.0.0 10000
  • -k означает keep-alive, что netcat продолжает прослушивать после каждого соединения
  • -ты означает UDP
  • -Я слушаю порт 10000
5

Отказавшись от netcat в моей версии ОС, она довольно короткая и выполняет свою работу:

#!/usr/bin/ruby
# Receive UDP packets bound for a port and output them
require 'socket'
require 'yaml'

unless ARGV.count == 2
puts "Usage: #{$0} listen_ip port_number"exit(1)
end
listen_ip = ARGV[0]
port = ARGV[1].to_i

u1 = UDPSocket.new
u1.bind(listen_ip, port)
while true
mesg, addr = u1.recvfrom(100000)
puts mesg
end
3

Как объясняет принятый ответ, ncat кажется не поддерживать --keep-open с протоколом UDP. Однако, сообщение об ошибке, которое это печатает, подсказывает обходной путь:

Ncat: UDP mode does not support the -k or --keep-open options, except with --exec or --sh-exec. QUITTING.

Просто добавив --exec /bin/cat позволяет --keep-open использоваться. И вход, и выход будут подключены к /bin/catс эффектом превращения его в «эхо-сервер», потому что все, что отправляет клиент, будет скопировано обратно на него.

Чтобы сделать что-то более полезное с вводом, мы можем использовать операторы перенаправления оболочки (таким образом, требуя --sh-exec вместо --exec). Чтобы увидеть данные на терминале, это работает:

ncat -k -l -u -p 12345 --sh-exec "cat > /proc/$$/fd/1"

Предостережение: приведенный выше пример отправляет данные на стандартный вывод ncat родительская оболочка, что может сбить с толку, если в сочетании с дополнительными перенаправлениями. Просто добавить весь вывод в файл проще:

ncat -k -l -u -p 12345 --sh-exec "cat >> ncat.out"
0
По вопросам рекламы [email protected]