Netcat / socat поведение с пайпингом и UDP?

22950
sdaau

Я думаю, это близко к 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было отправлено - однако, опять же, последовательные запуски этой команды не вызовут какого-либо приема на сервере, пока сервер не будет перезапущен.

12

3 ответа на вопрос

18
sdaau

Хорошо, я думаю, что по крайней мере я получил кое-что, 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
OldWolf

Ваш 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` "), однако, пока я вижу три `привета ', то, что меня озадачивает, все еще присутствует: эта команда тоже будет своего рода" блокировать ", как если бы она ждала ввод ввода от пользователя, а после Ctrl-C и его повторного запуска сервер не увидит любые данные, пока он не будет перезапущен !? Вот что я хотел бы узнать лучше - ура! sdaau 13 лет назад 0
nc ожидает EOF, который в этом случае не получает, пока вы не отправите сигнал выхода в программу. OldWolf 13 лет назад 2
Ааа, понятно - большое спасибо за это объяснение, @OldWolf! Кажется, `socat` может обойти это с помощью опции` fork` ... Еще раз спасибо, ура! sdaau 13 лет назад 0
2
pdragon

If you do an strace of the listening nc, it will show that netcat is waiting for the connection, and once it gets it, will connect to that host and port, ignoring all others. You need to add '-k' to keep going and '-w 0' to timeout each connection after 0 seconds. Socat is a better choice, I think.

Похожие вопросы