Подтвердить что ты не робот

Странное поведение 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?

4b9b3361

Ответ 1

Когда 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 a connect отклоняет все пакеты, которые не соответствуют IP и порту в connect.

Ответ 2

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

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

Ответ 3

Отказавшись от 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

Ответ 4

Как объясняет принятый ответ, 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 требуется --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"