我需要测试 TCP 数据的接收。我不得使用 iperf。
要求是说我应该创建一个 TCP 服务器,有人将向其发送随机数据。我需要计算收到的字节数。
我被告知要使用以下内容:
timeout 60 cat < /dev/tcp/IP_addr/port | wc –c > byte_count-n.txt
这会起到他们认为的作用吗?它会接收数据 60 秒,然后当超时到期时,将接收到的数据通过管道传输到wc
,从而将总数写入磁盘文件吗?
作为一名程序员,如果看到它我会感到更高兴
(timeout 60 cat < /dev/tcp/IP_addr/port) | wc –c > byte_count-n.txt
但显然 shell 不会接受这一点。我的担心正确吗?
请注意,我们使用的是 Ash shell,但有人担心只有 Bash 支持/dev/tcp
答案1
请注意,这个答案问题的早期版本该命令的本意是服务器。
没有bash
(以及ksh
该功能的来源),/dev/tcp/host/port
是旨在用于客户TCP 连接。
外壳会连接到主机:端口,并将该连接的套接字设置为重定向主题的 fd。使用<
or 时<>
,它是 fd 0 (stdin),使用 时>
,>>
它是 fd 1,但运算符没有区别。特别是,并不是因为您使用了<
shell 就关闭了套接字的发送方向;而是因为您使用了 shell。 stdin 仍将连接到您可以读取和写入的套接字。
如果您想监听(作为服务器)并接受一个或多个连接,则不能使用/dev/tcp/host/port
.
您需要使用专用工具,例如socat
或nc
,或者具有内置支持的外壳(例如zsh
其ztcp
内置工具)。
timeout 60 socat -u tcp-listen:12345,reuseaddr,bind=127.0.0.1,fork - | wc -c
将侦听环回 IPv4 地址上的端口 12345 并接受子进程中的传入连接,将接收到的内容写入 stdout(此处通过管道传输到wc
)。
nc
名为或的工具有多种实现netcat
,您通常可以使用它们执行相同的操作:
timeout 60 nc -l 127.0.0.1 12345 | wc -c
请注意,它运行该命令 60 秒。这包括它不做任何事情等待传入连接的时间。
如果您希望计时器在传入连接时启动,您可以这样做:
socat -u tcp-listen:12345,reuseaddr,bind=127.0.0.1 'EXEC:timeout 60 cat' | wc -c
这里只接受一个 TCP 连接(否fork
),然后通过管道传输到timeout 60 cat
。
只是为了澄清我认为您在这个主题中可能会问的问题,当您这样做时:
cmd1 | cmd2
它没有cmd1
运行,当它完成时,数据被发送到cmd2
.相反,cmd1
和cmd2
是同时启动的(它们并行运行),它们之间有一个管道(cmd1
的 stdout 是管道的写入端, cmd2 的 stdin 是读取端)。
在:
timeout 60 nc -l 127.0.0.1 12345 | wc -c
你已经timeout
并行wc
运行了。timeout
启动另一个执行它的进程nc
(它将共享相同的标准输出)。
60 秒后,timeout
将杀那个其他过程。此时nc
将退出,但它将将从套接字接收到的内容写入管道(nc
或者socat
不缓冲其输出),因此即使wc
尚未读取它,也会将其视为wc
将继续读取直到管道排空。
(timeout 60 nc ...) | wc –c
会是一样的。(code)
是启动一个子 shell(正在评估 的子 shell 进程(在 ksh93 以外的 shell 中)code
)。但在这里,由于它是管道的一部分,因此该代码必须已经位于子 shell 中(管道的不同部分必须在不同的进程中运行,因为它们同时运行)。