如何在 Rust 中正确地将 dd 命令传输到 netcat 命令?

发布于 2025-01-12 18:17:57 字数 1566 浏览 0 评论 0原文

我对 Rust 相当陌生,正在尝试将 dd 命令通过管道传递给 netcat 命令来检查两台机器之间的网络带宽。

总命令为: dd if=/dev/zero bs=16000 count=625 | nc -v <我的 IP> <端口号>。

到目前为止我的代码:

use std::process::Command;
use std::process::Stdio;
use std::io::Write;
use std::io::Read;
use std::fs::File;

fn main() 
{
    let mut dd_cmd = Command::new("dd")
                         .args(&["if=/dev/zero", "bs=16000", 
                                 "count=625"])
                         .output()
                         .unwrap();

    let mut nc_cmd = Command::new("nc")
                         .args(&["-v", "<my IP>", "<port Number>"])
                         .stdin(Stdio::piped())
                         .spawn()
                         .unwrap();

    nc_cmd.stdin.unwrap().write_all(&dd_cmd.stdout).unwrap();
 }

(注意:我知道我没有进行错误检查,并且我的 IP 地址和端口号的 nc 命令参数已更改。这样做是出于安全原因。)

我希望输出如下:

在此处输入图像描述

问题:

我可以成功地将文件传输到另一台计算机,并且文本显示在终端中。但是,在第一台机器上我没有收到任何有关网络带宽的信息。我在第一台机器的终端中看到的只是“...反向主机查找失败...”和“(未知)...”行。但是,如果我只是测试 dd 命令并将第 11 行从“.output()”更改为“.spawn()”,那么我就可以在第一台机器的终端中看到网络带宽信息。经过在线研究后,我了解到spawn()默认情况下会使stdin和stdout从父进程继承,而output()默认情况下会使stdin和stdout通过管道传输()。我不明白为什么我能够成功传输数据但丢失了实际的带宽信息。该信息不是 dd 命令输出的一部分吗?它不应该出现在传输数据的任何地方吗?

一个奇怪的结果:

我可以打开一个文件并将其写入 nc 命令的标准输入。当我这样做时,我实际上可以在第一台机器的终端中看到带宽信息!

I am fairly new to Rust and am trying to pipe a dd command to a netcat command to check the network bandwidth between two machines.

The total command is: dd if=/dev/zero bs=16000 count=625 | nc -v <my IP> <port number>.

My code so far:

use std::process::Command;
use std::process::Stdio;
use std::io::Write;
use std::io::Read;
use std::fs::File;

fn main() 
{
    let mut dd_cmd = Command::new("dd")
                         .args(&["if=/dev/zero", "bs=16000", 
                                 "count=625"])
                         .output()
                         .unwrap();

    let mut nc_cmd = Command::new("nc")
                         .args(&["-v", "<my IP>", "<port Number>"])
                         .stdin(Stdio::piped())
                         .spawn()
                         .unwrap();

    nc_cmd.stdin.unwrap().write_all(&dd_cmd.stdout).unwrap();
 }

(Note: I am aware that I am not error checking and that my nc command arguments for IP address and port number are changed. This is done for security reasons.)

What I want the output to look like:

enter image description here

The Problem:

I can successfully transfer files to the other machine and the text shows up in the terminal. However, on the first machine I don't receive any information about the network bandwidth. All I see in the terminal of the first machine are the "...inverse host lookup failed..." and "(UNKNOWN)..." lines. But, if I just test the dd command and change line 11 from ".output()" to ".spawn()", then I am able to see the network bandwidth information in the terminal of the first machine. After researching online, I understand that spawn() will by default make the stdin and stdout inherit from the parent process and output() will by default make the stdin and stdout be piped(). I don't understand why I am able to successfully transfer the data but lose the actual bandwidth information. Is that information not a part of the dd command output? Shouldn't it show up wherever the transferred data does as well?

A weird result:

I can open up a file and write it to the stdin of the nc command. When I do it this way, I can actually see the bandwidth information in the terminal of the first machine!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜无邪 2025-01-19 18:17:58

我不明白为什么我能够成功传输数据但丢失了实际的带宽信息。该信息不是 dd 命令输出的一部分吗?它不应该出现在传输数据的任何地方吗?

您是否希望将使用 dd 传输的数据与 dd 的统计报告混合在一起?这听起来像是会破坏你正在传输的任何东西。

或者至少 dd 的设计者是这么认为的,这就是为什么 dd 将其传输的数据发送到 stdout,而将自己的数据发送到 stderr。因此,如果您想将两者都发送到管道中的下一个阶段,则需要将两者都发送。

或者您的意思是,当您运行此命令时,来自 dd 的信息不会显示在您的终端中?那是因为

默认情况下,捕获 stdout 和 stderr(并用于提供结果输出)。

因此,stderr 被捕获,存储在缓冲区中,然后在程序终止时掉落在地上。

顺便说一句,您的 dd 在这里似乎不太有用:output 将启动子进程,等到它终止,并将其所有输出收集在 Vec< 中;u8>。所以这是一个非常复杂且低效的版本:

vec![0u8;10_000_000]

I don't understand why I am able to successfully transfer the data but lose the actual bandwidth information. Is that information not a part of the dd command output? Shouldn't it show up wherever the transferred data does as well?

Would you want the data you're transferring with dd and dd's stats reporting to be intermixed? That sounds like something which would break whatever you're transferring.

Or at least dd's designers thought so, which is why dd sends the data it transfers to stdout, but sends its own data to stderr. So if you want to send both over to the next stage in your pipeline, you need to send both.

Or maybe you mean that when you run this the information from dd does not show up in your terminal? That would be because

By default, stdout and stderr are captured (and used to provide the resulting output).

So stderr is captured, stored in a buffer, then dropped on the ground when the program terminates.

Incidentally your dd does not seem very useful here: output is going to start the child process, wait until it terminates, and collect all of its output in a Vec<u8>. So it's a very complicated and inefficient version of:

vec![0u8;10_000_000]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文