Получение нескольких файлов одновременно в Netcat без перезаписи последнего файла
1 машина слушает (Linux), в то время как несколько клиентов (Windows) отправляют файлы на один и тот же порт прослушивания. NETcat получает файлы последовательно с тегом -k.
Listening machine:
nc -lp PORT -k > fileX
Clients:
nc IP PORT < file??
Я хочу получить несколько файлов из нескольких источников, БЕЗ их перезаписи друг на друга.
Пожалуйста, посмотрите на предыдущие команды. Машина слушателя всегда записывает вывод в fileX, перезаписывая таким образом файл предыдущего клиента.
Я хочу как-то иметь возможность изменить имя выходного файла для каждого клиента. Может ли клиент как-то отправить строку "file10" через netcat и сказать слушателю, что нужно выводить в> file10?
Спасибо.
РЕДАКТИРОВАТЬ: Придумал идею:
Это автоматизировано с помощью скрипта:
Во-первых, слушатель устанавливает выходной файл в файл file.txt. (nc -lp PORT > file.txt)
Клиент отправляет строку (например, "file123") через netcat. (Это будет имя файла, который будет отправлен в будущем.)
Слушатель пишет в file.txt, затем читает file.txt и запускает новый прослушиватель netcat с выходным файлом> file123
Наконец, клиент отправляет данные.
2 ответа
Этот другой ответ обсуждает смысл вашего собственного протокола / установки. Я не буду повторять это. Я предполагаю, что ваше собственное решение - то, что вы хотите.
nc -k
не лучший инструмент для получения "нескольких файлов из нескольких источников", потому что он будет прослушивать другое соединение только после завершения текущего. Это означает, что он будет получать несколько файлов, но один за другим, а не параллельно. Ваши "несколько источников" будут блокировать друг друга.
socat
с reuseaddr
а также fork
может быть лучше.
В качестве доказательства концепции давайте создадим (быстрым и грязным способом) наш собственный протокол. Файл будет передан в виде потока, который состоит из:
- имя файла или путь для использования на принимающей стороне (без перевода строки);
- одиночный перевод строки (
\n
, LF, 0x0a) в качестве разделителя; - двоичные данные;
- 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="${f%$(printf "\r")}" && 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
использовался для проверки того, были ли копии ( скорее всего) такими же, как и оригиналы; они были.
Нет, обычный netcat не имеет таких специальных команд. Он не интерпретирует входные данные, и на самом деле он даже не знает, что его ввод / вывод является файлом: перенаправление выполняется вашей оболочкой, а netcat не беспокоится о поиске.
Таким образом, вам нужна дополнительная программа, которая интерпретирует полученные данные и самостоятельно открывает выходные файлы. В конце концов, вы бы практически изобрели tar
, (Или жеcpio
или дюжина других похожих форматов.)
[client] tar -cf - fileXYZ | nc <ip> <port>
[server] nc -lp <port> | tar -xvf -
Существуют сборки GNUtar для Windows, и недавно начал работать Win10, включая bsdtar. Если ни один из них недоступен, вам придется создать собственный протокол - например, отправить имя файла в первой строке, а затем данные; вам нужно написать собственный код для отправителя и получателя.
Группировка нескольких команд в круглых скобках как единый конвейер поможет:
[client] (echo fileXYZ && type fileXYZ) | nc <ip> <port>
[server] nc -lp <port> | (read name; name=${name##*/}; name=${name%$'\r'}; cat > "$name")
Но вместо этого я бы настроил Samba на компьютере с Linux и настроил общий ресурс, чтобы клиенты могли просто copy fileXYZ \\<ip>\incoming\fileXYZ
,