Странное поведение netcat с UDP - PullRequest
32 голосов
/ 08 октября 2011

Я заметил странное поведение при работе с 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?

Ответы [ 4 ]

40 голосов
/ 08 октября 2011

Когда 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, настроил его для повторного использования адреса и привязал его к порту 10000. Как только он получил свою первую дейтаграмму (от порта 52 832), он выпустил системный вызов connect, «соединяющий» ее с 127.0.0.1:52 832. Для UDP connect отклоняет все пакеты, которые не соответствуют IP-адресу и порту в connect.

5 голосов
/ 01 марта 2015

Используйте параметр -k:

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

Отказавшись от 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
0 голосов
/ 05 декабря 2018

Как объясняется в принятом ответе, 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, что сделает его «эхо-сервером», потому что все, что отправляет клиент, будет скопировано обратно на него.

Чтобы сделать что-то более полезное с вводом,мы можем использовать операторы перенаправления оболочки (таким образом, вместо --exec требуется --sh-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"
...