Поведение Netcat / socat с конвейером и UDP?


16

Я думаю, это близко к Linux - Netcat перестает слушать трафик UDP - Super User , но я подумал, что лучше спросить в любом случае

Что касается версий netcat, я использую Ubuntu 11.04 и значение netcatпо умолчанию для него, которое я предполагаю, это openbsd:

$ nc
This is nc from the netcat-openbsd package. An alternative nc is available
in the netcat-traditional package.
usage: nc [-46DdhklnrStUuvzC] [-i interval] [-P proxy_username] [-p source_port]
      [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_protocol]
      [-x proxy_address[:port]] [hostname] [port[s]]

 

Это то, что я нахожу странным: первый случай работает как положено - я открываю сервер UDP в одном терминале:

$ sudo nc -ul 5000

... а в другом терминале я инициирую новое соединение с UDP-клиентом - и набираю helloтри раза, нажимая клавишу ВВОД после каждого:

$ nc -u 127.0.0.1 5000
hello
hello
hello
^C

... и возвращаясь к серверному терминалу, он напечатал helloтри раза, как и ожидалось:

$ sudo nc -ul 5000 
hello
hello
hello
^C

 

Пока все хорошо, все работает как положено. Однако, допустим, я сейчас пытаюсь сделать то же самое, передавая данные в клиент; поэтому сначала установите UDP-сервер в одном терминале:

$ sudo nc -ul 5000

... а в другом случае передайте некоторые данные в ncкачестве клиента UDP:

$ echo hello | nc -u 127.0.0.1 5000
hello
hello
^C

... после команды клиента оболочка как бы зависает, как будто ожидает ввода - поэтому я набираю helloи еще два раза ВВОД; но сервер зарегистрировал только первый hello(который был передан по каналу echo). Более того, даже если вы нажмете Ctrl-C и попытаетесь повторить команду клиента echo hello | nc -u 127.0.0.1 5000, сервер все равно останется сообщившим только самое первое hello:

$ sudo nc -ul 57130 
hello
^C

... и только после остановки сервера с помощью Ctrl-C и его повторного запуска можно повторить команду клиента echo hello | nc -u 127.0.0.1 5000и наблюдать за ее работой.

 

Это способ ncвести себя? Я ожидал бы, что по крайней мере повторные вызовы echo hello | nc -u 127.0.0.1 5000будут зарегистрированы - без перезагрузки сервера? Или, может быть, есть специальный переключатель командной строки для такого поведения?

EDIT: Я нашел хороший PDF презентацию: SOCAT - Обработка всех видов сокетов , который содержит следующие netcatпротив socatпримечания:

netcat - ограничения
● только один выстрел (завершается после закрытия сокета)
...
Примеры 1: замена netcat
...
● UDP-клиент с портом источника:
nc -u -p 500 1.2.3.4 500
socat - udp: 1.2.3.4: 500, sp = 500
● TCP-сервер:
nc -l -p 8080
socat - tcp-l: 8080, reuseaddr
...

... тем не менее, я получаю то же поведение, что и выше, если я заменю команду сервера на " socat - udp4-listen:5000,reuseaddr" - и строку клиента на " socat - udp:127.0.0.1:5000" ... с вводом по трубопроводу " echo hello | socat - udp:127.0.0.1:5000", единственное отличие состоит в том, что здесь команда, по крайней мере, существует после того, как слово helloбыло отправлено - однако, опять же, последовательные запуски этой команды не вызовут какого-либо приема на сервере, пока сервер не будет перезапущен.

Ответы:


23

Хорошо, я думаю, что, по крайней мере, я получил кое-что, socatа именно, опция forkдолжна быть добавлена ​​к строке сервера:

$ socat - udp4-listen:5000,reuseaddr,fork

... а затем, в другом терминале, мы можем несколько раз вызвать команду echopiping в socatклиентскую строку в командной строке, так как она завершится немедленно ( ну, через полсекунды :) ):

$ echo "hello" | socat - udp-sendto:127.0.0.1:5000
$ echo "hello" | socat - udp-sendto:127.0.0.1:5000
$ echo "hello" | socat - udp-sendto:127.0.0.1:5000

... и возвращаясь к первому терминалу, мы видим, что сервер успешно показал все три значения hello:

$ socat - udp4-listen:5000,reuseaddr,fork
hello
hello
hello
^C

 

Обратите внимание, что даже с сервером fork-ed socatлиния echo "hello" | nc -u 127.0.0.1 5000все равно будет «блокироваться», как будто ожидает ввода пользователя; однако теперь после Ctrl-C и повторного запуска команды, т.е.

$ echo "hello" | nc -u 127.0.0.1 5000
^C
$ echo "hello" | nc -u 127.0.0.1 5000
^C
$ echo "hello" | nc -u 127.0.0.1 5000
^C

... сервер fork-ed socatпокажет три helloсекунды без необходимости перезапуска ..

 

Похоже, у этого openBSD netcatнет forkопции - но я не уверен, есть ли у него соответствующий ему ..

В любом случае, надеюсь, это поможет кому-то,
ура!


4

Ваш netcat только читает вывод из stdout echo, когда вы используете pipe, он больше не «подключен» к клавиатуре. Чтобы получить ожидаемый ответ, вы можете добавить свои три "привет" в файл запустить

cat [myfile] | nc -u 127.0.0.1 5000

Привет @OldWolf - большое спасибо за ваш ответ! Я попробовал ваше предложение (также несколько более запутанным образом, " cat $(echo -e "hello\nhello\nhello\n" > tmpf; echo tmpf) | nc -u 127.0.0.1 5000"), однако, хотя я вижу три helloсекунды, то, что меня озадачивает, все еще присутствует: эта команда тоже будет своего рода "блокировать", как будто ожидая ввода ввода от пользователь, и после Ctrl-C и перезапуска сервер не увидит никаких данных, пока не будет перезапущен !? Вот что я хотел бы узнать лучше - ура!
sdaau

2
nc ожидает EOF, который в этом случае не получает, пока вы не отправите сигнал выхода в программу.
OldWolf

Ааа, понятно - большое спасибо за это объяснение, @OldWolf! Кажется, socatможно обойти это с forkопцией ... Еще раз спасибо, ура!
sdaau

3

Если вы выполните несколько шагов прослушивания nc, он покажет, что netcat ожидает соединения, и, как только он его получит, подключится к этому хосту и порту, игнорируя все остальные. Вы должны добавить '-k', чтобы продолжить работу, и '-w 0', чтобы отключить каждое соединение через 0 секунд. Думаю, Сокат - лучший выбор.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.