Получение нескольких файлов одновременно в Netcat без перезаписи последнего файла

358
MyWays

1 машина слушает (Linux), в то время как несколько клиентов (Windows) отправляют файлы на один и тот же порт прослушивания. Netcat получает файлы последовательно с тегом -k.

Listening machine:  nc -lp PORT -k > fileX Clients:  nc IP PORT < file?? 

Я хочу получить несколько файлов из разных источников, БЕЗ их перезаписи друг на друга.

Пожалуйста, посмотрите на предыдущие команды. Машина слушателя всегда записывает вывод в fileX, перезаписывая, таким образом, файл предыдущего клиента.

Я хочу как-то иметь возможность изменить имя выходного файла для каждого клиента. Может ли клиент как-то отправить строку «file10» через netcat и сказать слушателю, что нужно выводить в> file10?

Спасибо.

РЕДАКТИРОВАТЬ: Придумал идею:

Это автоматизировано с помощью скрипта:

  1. Во-первых, слушатель устанавливает выходной файл в файл file.txt. (nc -lp PORT> file.txt)

  2. Клиент отправляет строку (например, «file123») через netcat. (Это будет имя файла, который будет отправлен в будущем.)

  3. Слушатель пишет в file.txt, затем читает file.txt и запускает новый прослушиватель netcat с выходным файлом> file123

  4. Наконец, клиент отправляет данные.

0

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

0
grawity

Нет, обычный netcat не имеет таких специальных команд. Он не интерпретирует свой ввод, и на самом деле он даже не знает, что его ввод / вывод является файлом: перенаправление выполняется вашей оболочкой, и netcat не беспокоится о поиске.

Таким образом, требуется дополнительная программа, которая делает интерпретации принятые входным и открывает выходные файлы самостоятельно. В конце концов, вы бы практически заново изобрели tar. (Или cpioдюжина других похожих форматов.)

[client] tar -cf - fileXYZ | nc <ip> <port> [server] nc -lp <port> | tar -xvf - 

Существуют сборки GNU tar для Windows, и недавно начал работать Win10, включая bsdtar . Если ни один из них недоступен, вам придется создать собственный протокол - например, отправить имя файла в первой строке, а затем данные; вам нужно написать собственный код для отправителя и получателя.

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

[client] (echo fileXYZ && type fileXYZ) | nc <ip> <port> [server] nc -lp <port> | (read name; name=$; name=$; cat > "$name") 

Но вместо этого я бы настроил Samba на Linux-машине и настроил публичный общий ресурс, чтобы клиенты могли просто copy fileXYZ \\<ip>\incoming\fileXYZ.

«… Создайте свой собственный протокол» - ник OP - MyWays. : D Kamil Maciorowski 5 лет назад 0
@ grawity Спасибо за ответ. Я буду стараться. Пожалуйста, прочитайте мой ответ еще раз, как я добавил идею и скажите мне, что вы думаете? MyWays 5 лет назад 0
@KamilMaciorowski Ха-ха, что это должно означать? MyWays 5 лет назад 0
@MyWays Вы можете изобретать «tar» по-своему. Kamil Maciorowski 5 лет назад 0
это мой путь или tarway, JK. Моя редакция хорошая идея? MyWays 5 лет назад 0
0
Kamil Maciorowski

Этот другой ответ обсуждает смысл вашего собственного протокола / установки. Я не буду повторять это. Я предполагаю, что ваше собственное решение - то, что вы хотите.

nc -kне лучший инструмент для получения «нескольких файлов из нескольких источников», потому что он будет прослушивать другое соединение только после завершения текущего. Это означает, что он будет получать несколько файлов, но один за другим, а не параллельно. Ваши «несколько источников» будут блокировать друг друга.

socatс reuseaddrи forkможет быть лучше.

В качестве доказательства концепции давайте создадим ( быстрым и грязным способом) наш собственный протокол. Файл будет передан в виде потока, который состоит из:

  1. имя файла или путь для использования на принимающей стороне (без перевода строки);
  2. одиночная \nновая строка (, LF, 0x0a) в качестве разделителя;
  3. двоичные данные;
  4. EOF.

Это принимающая команда:

socat TCP-LISTEN:50011,reuseaddr,fork SYSTEM:'read -r f && cat >"$f"' 

(Изменить) Это универсальная команда приема, которая удаляет конечный \r(если он есть) из имени файла (полезно для работы с клиентами Windows, не полностью совместимыми с протоколом):

socat TCP-LISTEN:50011,reuseaddr,fork SYSTEM:'read -r f && f="$" && cat >"$f"' 

(Редактирование заканчивается здесь).

Чтобы отправить файл:

(echo "The new name.foo" && cat "./the file to send.bar") > /dev/tcp/192.168.22.33/50011 

Заметки:

  • 50011 номер порта TCP, вы можете выбрать свой;
  • 192.168.22.33 это адрес сервера, измените его в соответствии с вашими настройками;
  • Я использовал /dev/tcp/…/…синтаксис, который работает в Bash, по каналу, ncесли вы хотите / нужно;
  • коллизии имен файлов по-прежнему остаются проблемой, для их решения вам нужна некоторая логика сценария (а не простая cat);
  • SYSTEMимеет свои ограничения (см. man socat); вместо того, чтобы передавать ему большое тело скрипта, запишите скрипт в файл и запустите файл; Вы также можете расследовать EXEC;
  • наш протокол (быстрый и грязный) не предоставляет серверу никакого способа сообщать об ошибках (если таковые имеются) или об успехе клиенту.

Я проверял это с получателем Debian и отправителем Ubuntu. В один момент три разных соединения передавали три разных файла с двух разных IP-адресов. После завершения всех передач md5sumиспользовался для проверки того, были ли копии ( скорее всего ) такими же, как и оригиналы; они были.

Ницца. Как я могу отправить файл, если клиент Windows? Я попытался в PowerShell .. Это, как далеко я получил. $ file = Get-Content ./somefile; echo "filename10" $ file | ./Netcat32 IP PORT. На Linux-машине я получаю файл с именем "filename10" $ '\ r' "(без двойных кавычек). Содержимое файла правильное, но имя файла отключено. MyWays 5 лет назад 0
@ MyWays Я не могу помочь вам с этим кодом PowerShell (я парень из Linux, я никогда не работал с PowerShell), но проблема выглядит как вызванная [различными окончаниями строк в Windows и в Unix] (https: // en .wikipedia.org / вики / Newline # Issues_with_different_newline_formats). Kamil Maciorowski 5 лет назад 0
@MyWays Хотя правильный код между `read` и` cat` в Linux может это исправить. Дай мне пару минут. Kamil Maciorowski 5 лет назад 0
@ MyWays Мой ответ теперь решает эту проблему. Kamil Maciorowski 5 лет назад 0
это какое-то волшебство прямо здесь. MyWays 5 лет назад 0
Извините, что угнали, так как на этом форуме, по-видимому, нет опции PM, но как закрыть соединение на клиенте после завершения передачи файла? Я получил netcat версии 1.11 для Windows, у которой нет параметра -q, как у nc в Linux. MyWays 5 лет назад 0
Давайте [продолжим обсуждение в чате] (https://chat.stackexchange.com/rooms/84756/discussion-between-kamil-maciorowski-and-myways). Kamil Maciorowski 5 лет назад 0