Как создать TCP-соединение, используя nc
, которое прослушивает несколько хостов?
nc -l -p 12345
Как создать TCP-соединение, используя nc
, которое прослушивает несколько хостов?
nc -l -p 12345
Одновременные соединения невозможны с netcat
. Вы должны использовать что-то вроде инструмента tcpserver
ucspi-tcp
или xinetd
, так как вы работаете в Linux.
См.: https://superuser.com/questions/232747/netcat-as-a-multithread-server
Последовательные соединения могут быть обработаны с помощью сценария оболочки, который перезапускает netcat
после завершения.
ncat
может это сделать.
Например. ncat --broker --listen -p 12345
будет распределять все входящие сообщения всем другим клиентам (представьте себе, что это концентратор).
ncat -l -p 12345
делает то, что хотел ОП. Пример с использованием --broker
интересен, но не относится к этому конкретному вопросу.
- person Todd Owen; 19.10.2018
ncat -k -l -p 12345
? Вы правы, командная строка, которую я разместил выше, не работает, но --broker
заставит процесс прослушивания ничего не выводить на стандартный вывод, вместо этого копируя все данные, которые он получает, обратно (другим) клиентам, что определенно не то, что OP попросил о.
- person Todd Owen; 29.11.2018
-u
для выбора протокола UDP вместо TCP по умолчанию. Согласно этот ответ, он не поддерживает это (и не поддерживает --broker
с UDP). Однако ознакомьтесь с обходным решением, которое я только что опубликовал.
- person Todd Owen; 05.12.2018
Я рекомендую socat
как альтернативу nc
.
Для проблемы ОП socat - TCP-LISTEN:12345,fork,reuseaddr
может выполнить эту работу.
-k
Заставляет nc продолжать прослушивание другого соединения после завершения текущего соединения. Использование этой опции без опции -l является ошибкой.
с помощью nc
невозможно открыть параллельные подключения к одному и тому же порту, однако вы можете обмануть nc
, чтобы открыть несколько подключений к одному и тому же порту.
Чтобы понять это, предположим, вы начинаете прослушивать 4444
порт, используя $ nc -l -p 4444 -v
. Теперь, если вы проверите вывод $ netstat -anp | grep 4444
, вы получите его состояние как LISTEN, и здесь его pid равен 3410.
tcp 0 0 0.0.0.0:4444 0.0.0.0:* LISTEN 3410/nc
Теперь, после того, как он подключится к клиенту, скажем, вы запустите $ nc localhost 4444 -v
, его состояние изменится на ESTABLISHED. Теперь попробуйте запустить $ netstat -anp | grep 4444
, вы получите его состояние ESTABLISHED, см. тот же pid 3410 и клиентский процесс с pid 3435.
tcp 0 0 127.0.0.1:46678 127.0.0.1:4444 ESTABLISHED 3435/nc
tcp 0 0 127.0.0.1:4444 127.0.0.1:46678 ESTABLISHED 3410/nc
Обратите внимание, что нет доступного прослушивающего порта, поэтому у вас не может быть другого клиентского процесса. Однако, если вы снова запустите $ nc -l -p 4444 -v
, у вас может быть порт прослушивания и может быть несколько клиентских процессов.
см. вывод netstat -anp | grep 4444
после того, как вы начнете прослушивать тот же порт.
tcp 0 0 0.0.0.0:4444 0.0.0.0:* LISTEN 3476/nc
tcp 0 0 127.0.0.1:46678 127.0.0.1:4444 ESTABLISHED 3435/nc
tcp 0 0 127.0.0.1:4444 127.0.0.1:46678 ESTABLISHED 3410/nc
см. вывод netstat -anp | grep 4444
после подключения нового клиента к тому же порту.
tcp 0 0 127.0.0.1:4444 127.0.0.1:46694 ESTABLISHED 3476/nc
tcp 0 0 127.0.0.1:46678 127.0.0.1:4444 ESTABLISHED 3435/nc
tcp 0 0 127.0.0.1:4444 127.0.0.1:46678 ESTABLISHED 3410/nc
tcp 0 0 127.0.0.1:46694 127.0.0.1:4444 ESTABLISHED 3483/nc
Вы можете сказать, что поведение подключений похоже на:
SERVER_PROCESS_1 <---> CLIENT_PROCESS_1
SERVER_PROCESS_2 <---> CLIENT_PROCESS_2
поэтому вы можете написать какой-нибудь скрипт для имитации этого поведения или использовать этот скрипт bash для изменения.
#!/usr/bin/bash
lport="4444"
i=0;
while [ true ]; do
echo "opening socket $(( i++ ))";
if [[ "$(ss sport = :$lport -l -H | wc -l)" -eq 0 ]]; then
nc -l -vv -p $lport &
#do something else to process or attach different command to each diff server process
fi;
if [[ "$(ss sport = :$lport -l -H | wc -l)" -ne 0 ]]; then
watch -n 0.1 -g "ss sport = :$lport -l -H" > /dev/null;
fi;
if [[ i -eq 10 ]]; then
break;
fi;
done;
здесь каждый раз, когда клиент использует соединение, этот скрипт запускает новый сокет прослушивания.
Однако это поведение можно изменить в ncat
(здесь, используя -k
), как вы можете проанализировать с помощью приведенного ниже примера:
сервер запускается с использованием $ ncat -l -p 4444 -v -4 -k
и 3 клиента запускаются с использованием $ ncat -4 localhost 4444
. Теперь вывод для $ netstat -anp | grep 4444
:
tcp 0 0 0.0.0.0:4444 0.0.0.0:* LISTEN 3596/ncat
tcp 0 0 127.0.0.1:4444 127.0.0.1:46726 ESTABLISHED 3596/ncat
tcp 0 0 127.0.0.1:46726 127.0.0.1:4444 ESTABLISHED 3602/ncat
tcp 0 0 127.0.0.1:46722 127.0.0.1:4444 ESTABLISHED 3597/ncat
tcp 0 0 127.0.0.1:4444 127.0.0.1:46724 ESTABLISHED 3596/ncat
tcp 0 0 127.0.0.1:4444 127.0.0.1:46722 ESTABLISHED 3596/ncat
tcp 0 0 127.0.0.1:46724 127.0.0.1:4444 ESTABLISHED 3601/ncat
Каждый раз, когда подключается новый клиент, сервер разветвляет свой процесс для подключения к клиенту, поэтому каждый серверный процесс использует один и тот же pid. Таким образом, выходные данные сервера распределяются между всеми подключенными клиентами, однако каждый клиент может отправлять отдельное сообщение на сервер.
Вы можете сказать, что поведение подключений похоже на:
SERVER_PROCESS_1 <---> CLIENT_PROCESS_1
SERVER_PROCESS_1 <---> CLIENT_PROCESS_2
SERVER_PROCESS_1 <---> CLIENT_PROCESS_3
без -k
ncat
будет вести себя так же, как nc
.
Выгоды или потери можно определить по тому, как они должны быть необходимы.
В этом примере я использовал nc
или nc.traditional
(v1.10-41.1+b1) и ncat
(7.80).
Это неполный ответ, потому что у меня он не работает. На самом деле, пожалуй, больше вопрос. Может, кто-нибудь другой сможет его закончить.
Во-первых, похоже, существуют разные версии netcat. Я использую Ubuntu, поэтому, вероятно, у меня есть версия, поставляемая с Ubuntu. Когда я nc -h
, он говорит следующее:
OpenBSD netcat (Debian patchlevel 1.187-1ubuntu0.1)
Когда я запускаю man nc
, он говорит следующее:
-F Pass the first connected socket using sendmsg(2) to stdout and exit. This
is useful in conjunction with -X to have nc perform connection setup with
a proxy but then leave the rest of the connection to another program (e.g.
ssh(1) using the ssh_config(5) ProxyUseFdpass option).
Мне кажется, это означает, что вместо того, чтобы делать обычное дело с stdin и stdout, он просто печатает что-то на stdout. Затем это что-то может быть использовано другим процессом для фактического подключения к клиенту.
К сожалению, я не вижу эффекта -F
. Так что, возможно, я делаю это неправильно. Или, может быть, где-то есть какая-то секретная трубка, которую я должен выслушать, или дополнительный аргумент, который они забыли задокументировать. Или, может быть, у меня сломанная сборка netcat, и она работает для всех остальных, кто использует Ubuntu.
В сочетании с параметром -k
(или, в противном случае, с циклом while-true) это позволит многим различным клиентам иметь отдельные соединения. Предположим, у вас есть исполняемый файл с именем handle_connection
, который принимает в качестве аргументов входящий файловый дескриптор от клиента и исходящий файловый дескриптор для клиента и порождает подпроцесс, который взаимодействует с клиентом. Тогда скрипт сервера может выглядеть так:
nc -lkF $host $port | while read in out ; do
handle_connection $in $out ;
done
ncat
может это сделать, но правильная команда с ncat:
ncat --keep-open --listen -p 12345
Это позволит принимать несколько подключений одновременно.
Затем вы можете отправить данные нескольким клиентам. например откройте в двух или более терминалах и попробуйте ввести там:
nc localhost 12345
nc
(например, от группы других клиентов) или хотите ли вы прослушивать на несколько TCP/IP адреса вместо того, чтобы слушать по одному и сделать заголовок и текст совместимыми - person Hans Z.   schedule 20.04.2015