最近我在 QNX 文档中发现它允许使用串行设备 ( ) 在单独的物理机上的进程之间设置基于消息的 IPC,dev/serX
这让我想知道:
Linux 中是否可以为 TCP/UDP 隧道创建系统范围的特殊设备?像nc
stdin/stdout 这样的东西在 /dev/something 下公开暴露。
最后,我希望能够在一台机器上向此类文件写入一些内容并在另一端接收它,例如:
#machine1:
echo "Hello" > /dev/somedev
#machine2:
cat < /dev/somedev
我查看了nc
man,但没有找到除 stdio 之外的任何指定 io 源/目标的选项。
答案1
socat
可以用类似“流”的东西来做这个和许多其他事情
使用这个基本思想的东西应该可以为你做到:
Machine1$ socat tcp-l:54321,reuseaddr,fork pty,link=/tmp/netchardev,waitslave
Machine2$ socat pty,link=/tmp/netchardev,waitslave tcp:machine1:54321
(改编自示例页)
如果你想加密,你可以使用ssl-l:54321,reuseaddr,cert=server.pem,cafile=client.crt,fork
on machine1 的变体,以及类似ssl:server-host:1443,cert=client.pem,cafile=server.crt
on machine2 的东西
(更多关于索卡特SSL)
答案2
消息传递需要在更高层实现; TCP 没有消息的概念——TCP 连接传输八位字节流。
你可以实现类似于你所要求的东西nc
和命名管道, 看man mkfifo
;或者socat
按照 Alex Stragies 的指示进行检查。
如果没有中间层服务,基本问题是 (1) 数据无法写入网络,除非另一端有人监听数据,以及 (2) TCP 连接是双向的。
因为除非有人监听,否则您无法将数据写入网络,因此您必须始终启动监听器前你可以发送数据。 (在消息传递系统中,处理消息的进程将提供某种缓冲。)
您的示例可以轻松重写:
首先在 machine2(目标)上启动一个侦听器:
nc -l 1234 | ...some processing with the received data...
在你的例子中,这将是
nc -l 1234 | cat
这将阻塞并等待有人向端口 1234 发送一些数据。
然后您可以从 machine1(源)发送一些数据:
...make up some data... | nc machine2 1234
在你的例子中,这将是
echo "Hello" | nc machine2 1234
如果您想以某种方式处理接收到的数据并做出响应,您可以使用 shell 的协处理功能。例如,这是一个非常简单(而且非常顽固)的网络服务器:
#! /bin/bash
while :; do
coproc ncfd { nc -l 1234; }
while :; do
read line <&${ncfd[0]} || break
line="$(
echo "$line" |
LC_ALL=C tr -cd ' -~'
)"
echo >&2 "Received: \"$line\""
if [ "$line" = "" ]; then
echo >&${ncfd[1]} "HTTP/1.0 200 OK"
echo >&${ncfd[1]} "Content-Type: text/html"
echo >&${ncfd[1]} "Connection: close"
echo >&${ncfd[1]} ""
echo >&${ncfd[1]} "<title>It works!</title>"
echo >&${ncfd[1]} "<center><b>It works!</b></center>"
echo >&${ncfd[1]} "<center>-- $(date +%Y-%m-%d\ %H:%M:%S) --</center>"
break
fi
done
kill %%
sleep 0.1
done
了解如何使用数组中的文件描述符在脚本主体和协进程之间实现双向通信$ncfd
。
答案3
如果您只想使用 nc 等基本程序连接两台计算机,您可以重定向 from/to /dev/tcp/<host>/<port>
。
这些不是实际的设备,而是由 bash 创建的虚构设备,因此类似的东西cat /dev/tcp/foo/19
不会起作用,但cat < /dev/tcp/foo/19
会起作用。