Поведінка Netcat / socat з трубопроводами та UDP?


16

Я думаю, це близько до Linux - Netcat перестає слухати UDP-трафік - Супер Користувач , але я подумав, що краще все-таки запитати

Що стосується версій 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три рази, натискаючи ENTER після кожного:

$ 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 - Обробка всіх видів Sockets , яка містить такі 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

... а потім, в іншому терміналі, ми можемо викликати echoтрубопровід у 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

... і повернувшись до першого терміналу, ми можемо побачити, що сервер успішно показав усі три hellos:

$ 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покаже три hellos без необхідності перезапуску ..

 

Здається, у цього openBSD netcatнемає forkможливості - але я не впевнений, чи є у нього відповідний ..

У будь-якому випадку, сподівайтеся, що це допоможе комусь,
ура!


4

Ваш netcat лише зчитує висновок з виходу ехо, коли ви використовуєте трубу, він більше не "підключений" до клавіатури. Щоб отримати відповідь, яку ви очікуєте, ви можете додати свої три "привіт" у файл

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 секунд. Socat - кращий вибір, я думаю.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.