Как прослушивать несколько TCP-соединений с помощью nc

Как создать TCP-соединение, используя nc, которое прослушивает несколько хостов?

nc -l -p 12345

person Aman Jain    schedule 19.04.2015    source источник
comment
вы можете уточнить, хотите ли вы создать несколько TCP-подключений к nc (например, от группы других клиентов) или хотите ли вы прослушивать на несколько TCP/IP адреса вместо того, чтобы слушать по одному и сделать заголовок и текст совместимыми   -  person Hans Z.    schedule 20.04.2015
comment
@ХансЗ. несколько TCP-подключений, чтобы несколько клиентов подключались к одному сокету.   -  person Aman Jain    schedule 21.04.2015


Ответы (7)


Одновременные соединения невозможны с netcat. Вы должны использовать что-то вроде инструмента tcpserver ucspi-tcp или xinetd, так как вы работаете в Linux.

См.: https://superuser.com/questions/232747/netcat-as-a-multithread-server

Последовательные соединения могут быть обработаны с помощью сценария оболочки, который перезапускает netcat после завершения.

person Hans Z.    schedule 21.04.2015
comment
nc -k будет обрабатывать входящие соединения, когда предыдущее завершится, и все еще может принимать второе соединение при обработке первого. - person wizulus; 17.03.2017
comment
Спасибо @Hans Z... Не могли бы вы привести пример, поскольку в этой ссылке нет примера - person ; 21.01.2019

ncat может это сделать.

Например. ncat --broker --listen -p 12345 будет распределять все входящие сообщения всем другим клиентам (представьте себе, что это концентратор).

person masterxilo    schedule 18.12.2017
comment
это довольно ограничено / специализировано, но, конечно, полезно знать - person sehe; 30.07.2018
comment
Чтобы уточнить, ncat -l -p 12345 делает то, что хотел ОП. Пример с использованием --broker интересен, но не относится к этому конкретному вопросу. - person Todd Owen; 19.10.2018
comment
@ToddOwen неверно. Только что попробовал, при втором подключении всегда отказано в подключении. Использование --broker работает. - person Code Wiget; 28.11.2018
comment
@Ryan Не могли бы вы попробовать ncat -k -l -p 12345? Вы правы, командная строка, которую я разместил выше, не работает, но --broker заставит процесс прослушивания ничего не выводить на стандартный вывод, вместо этого копируя все данные, которые он получает, обратно (другим) клиентам, что определенно не то, что OP попросил о. - person Todd Owen; 29.11.2018
comment
@ToddOwen К сожалению, Ncat: режим UDP не поддерживает параметры -k или --keep-open, за исключением --exec или --sh-exec. ВЫХОД. - person Code Wiget; 04.12.2018
comment
@Ryan Похоже, вы добавляете -u для выбора протокола UDP вместо TCP по умолчанию. Согласно этот ответ, он не поддерживает это (и не поддерживает --broker с UDP). Однако ознакомьтесь с обходным решением, которое я только что опубликовал. - person Todd Owen; 05.12.2018
comment
Этот. является. удивительный. Я искал простой инструмент, который может сделать это уже почти год. - person James M. Lay; 15.02.2019

Я рекомендую socat как альтернативу nc.

Для проблемы ОП socat - TCP-LISTEN:12345,fork,reuseaddr может выполнить эту работу.

person dyng    schedule 14.07.2017

-k
Заставляет nc продолжать прослушивание другого соединения после завершения текущего соединения. Использование этой опции без опции -l является ошибкой.

person excitoon    schedule 12.01.2017
comment
Это не отвечает на вопрос ОП. Они хотели иметь возможность прослушивать два или более соединений одновременно, а не встречно-параллельные соединения. - person cascading-style; 23.02.2017
comment
Да, и это работает именно так, как просили. Как только первое соединение будет закрыто, оно распечатает пакеты из следующего. В противном случае вы получите беспорядок с данными из разных соединений. - person excitoon; 04.03.2017
comment
Это должен быть принятый ответ. С параметром -k netcat будет принимать несколько подключений, но обрабатывать их будет только по одному. Это был именно тот ответ, который я искал, когда попал на эту страницу. - person wizulus; 17.03.2017
comment
Я только что попробовал это и обнаружил, что (а) принимает несколько одновременных подключений и (б) печатает все данные по мере их получения. Это отличается от того, что наблюдали некоторые комментаторы выше, и мне интересно, действительно ли они видели эффекты буферизации где-то в системе? - person Todd Owen; 29.11.2018
comment
@wizulus Я не могу понять, почему кто-то хочет специально избегать двух подключений одновременно. Может быть, это то, чего вы хотите, я не оспариваю этого, но я не вижу никаких доказательств того, что это то, чего хочет ОП. Хорошо, что вы получили свой ответ, но это была случайность, и я, например, не думаю, что за ответ следует голосовать за ответ на неправильный вопрос. - person David Knipe; 24.08.2019
comment
@ToddOwen Я видел то же поведение, что и excitoon. Кроме того, excitoon делает хороший вывод: если одновременно присутствует несколько подключений, а netcat имеет только один STDIN и один STDOUT, как вы отделяете данные от/к одному клиенту от данных от/к другому? - person David Knipe; 24.08.2019
comment
@DavidKnipe Я понимаю путаницу. Я специально не хочу избегать двух подключений одновременно. Я хочу избежать отклонения одного соединения при одновременном подключении двух хостов. Без -k nc будет принимать соединение только с одного хоста, и даже если вы сразу снова запустите nc, всегда есть период времени, когда никто не слушает. Хорошая дискуссия. - person wizulus; 05.09.2019

с помощью 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).

person dinesh saini    schedule 23.12.2019

Это неполный ответ, потому что у меня он не работает. На самом деле, пожалуй, больше вопрос. Может, кто-нибудь другой сможет его закончить.

Во-первых, похоже, существуют разные версии 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
person David Knipe    schedule 23.08.2019

ncat может это сделать, но правильная команда с ncat:

ncat --keep-open --listen -p 12345

Это позволит принимать несколько подключений одновременно.

Затем вы можете отправить данные нескольким клиентам. например откройте в двух или более терминалах и попробуйте ввести там:

nc localhost 12345

person Alex Bozhenko    schedule 08.07.2021