1 台机器监听(linux),而多个客户端(windows)在同一个监听端口上向其发送文件。Netcat 使用 -k 标签串行接收文件。
Listening machine:
nc -lp PORT -k > fileX
Clients:
nc IP PORT < file??
我想要的是从多个来源接收多个文件,并且不让它们互相覆盖。
请查看前面的命令。监听器机器始终将输出写入 fileX,从而覆盖了前一个客户端的文件。
我希望能够以某种方式更改每个不同客户端的输出文件名。客户端能否以某种方式通过 netcat 发送字符串“file10”,从而告诉侦听器输出到 > file10 ?
谢谢。
编辑:想出了一个主意:
这是通过脚本自动完成的:
首先,监听器将输出文件设置为file.txt。(nc -lp PORT > file.txt)
客户端通过 netcat 发送字符串(例如“file123”)。(这将是将来要发送的文件的文件名。)
侦听器写入 file.txt,然后读取 file.txt,并使用输出文件 > file123 启动新的 netcat 侦听器
最后,客户端发送数据。
答案1
其他答案讨论了拥有自定义协议/设置的意义。我不会重复。我假设你的自己的解决方案就是您想要的。
nc -k
不是接收“来自多个来源的多个文件”的最佳工具,因为它仅在当前连接终止后才会监听另一个连接。这意味着它将接收多个文件,但会逐个接收,而不是并行接收。您的“多个来源”将相互阻塞。
socat
和reuseaddr
可能fork
会更好。
为了证明概念,我们来创建(在一个快速而肮脏方式)我们的自定义协议。文件将作为包含以下内容的流进行传输:
- 接收端使用的文件名或路径(不带换行符);
- 单个换行符(
\n
,LF,0x0a)作为分隔符; - 二进制数据;
- 结束。
这是接收命令:
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
用于验证副本是否正确(最有可能的) 与原件相同;它们是。
答案2
不,普通的 netcat 没有这样的特殊命令。它不解释其输入,实际上它甚至不知道其输入/输出是一个文件:重定向由您的 shell 完成,netcat 不会费心查找。
因此你需要一个额外的程序做解释收到的输入并自行打开输出文件。最后,您实际上会重新发明tar
。(或者cpio
,或者其他十几种类似格式。)
[client] tar -cf - fileXYZ | nc <ip> <port>
[server] nc -lp <port> | tar -xvf -
GNU 有 Windows 版本柏油并且 Win10 最近开始包括布斯达如果两者都不可用,则必须创建自己的协议 - 例如将文件名作为第一行发送,然后发送数据;您需要为发送方编写自定义代码和对于接收者来说。
将括号中的多个命令分组为单个管道单元将有助于:
[client] (echo fileXYZ && type fileXYZ) | nc <ip> <port>
[server] nc -lp <port> | (read name; name=${name##*/}; name=${name%$'\r'}; cat > "$name")
但是相反,我会在 Linux 机器上设置 Samba 并配置一个公共共享,以便客户端可以简单地copy fileXYZ \\<ip>\incoming\fileXYZ
。