【问题标题】:C/C++: is it possible to pass binary data through the console? [duplicate]C/C++:是否可以通过控制台传递二进制数据? [复制]
【发布时间】:2012-03-22 04:38:13
【问题描述】:

我想知道一个实用程序是否有可能产生二进制数据(即图形图像)并通过 IO 控制台输出它们,而另一个应用程序则指示这些数据的性质并通知传入字节的数量, 可以从 IO 控制台读取。

【问题讨论】:

    标签: c++ c console console-application binary-data


    【解决方案1】:

    是的,这是可能的。虽然stdin/stdout 通常是文本,但确实有许多程序旨在从标准 I/O 通道获取二进制输入或写入二进制输出。

    唯一需要注意的是stdout/stdin在Windows下一般都是以文本模式打开的,所以你应该将它们切换到二进制模式以避免字符转换。

    要在 Windows 上的 stdin/stdout 上设置二进制模式,您需要使用 _setmode 调用:

    #include <stdio.h>
    #include <fcntl.h>
    #include <io.h>
    
    int main( void )
    {
       int result;
    
       // Set "stdin" to have binary mode:
       result = _setmode( _fileno( stdin ), _O_BINARY );
       if( result == -1 )
          perror( "Cannot set mode" );
       else
          printf( "'stdin' successfully changed to binary mode\n" );
    }
    

    还要注意文件缓冲。通常只有当输出到交互式控制台而不是另一个进程时,程序才会在换行符上刷新缓冲区。因此,如果您需要同步,请记住在写完消息后调用fflush,否则其他进程将无法获取数据。

    【讨论】:

    • 为什么有些人在这里谈论Base64编码?如果不显示数据,Dervall 是否正确我不需要它? (数据其实不是)
    • @P5music:问他们。就像我说的,有许多程序可以输入或输出二进制数据(例如,您可以使用ffmpeg 解码电影并将输出写入原始 YUV 帧,以便另一个程序可以处理视频或在 Linux 中,如果你想对磁盘单元进行原始数据压缩备份,您可以使用dd -if=/dev/whatever | gz &gt; backup.dd.gz,它可以完美运行)。在windows上有这个令人讨厌的文本/二进制模式,但它是可以解决的。当然,将二进制数据扔到终端会很糟糕,但如果输出到另一个进程,那么一切都很好......
    • 请告诉我 printf 指令将数据(我知道字节数和指针)从 C 应用程序发送到控制台吗?
    • @P5music:只需使用fwrite(pointer, 1, number_of_bytes, stdout);,然后使用fflush(stdout);,以确保接收进程能够访问所有数据。
    • 谢谢!打扰一下,如果你也知道 C#,你能在这里看看我的另一个问题吗? stackoverflow.com/questions/9566211/…
    【解决方案2】:

    您可以Base 64-Encode/Decode 数据。这将避免需要通过标准输入/输出流发送纯“位”。

    【讨论】:

      【解决方案3】:

      你可以使用传统的socket或更轻的named pipe来处理这种事情。

      【讨论】:

        【解决方案4】:

        如果该进程将托管在另一个进程中,该进程将从写入二进制数据的进程中捕获您的标准输出,则无需对其进行编码。在这种情况下,您可以将原始二进制数据写入输出并完成它。例如,graphviz 的图像写入dot 工具是如何工作的,默认情况下它不会对其输入进行编码。通过在命令 shell 中使用&gt;,这些工具也很容易通过管道传输到文件。

        只有在控制台上可以看到数据的输出时,您才需要对其进行编码。打印图像文件的内容不是一个好主意。

        【讨论】:

        • 我可以用您描述的这种方法解决安全问题吗?
        • 我不是世界上最好的安全专家,但在我看来,无论你实际写什么,写到标准输出几乎都是一样的。只要您不将其打印到实际的控制台。如果您这样做,不会发生太多事情,它只会打印一堆时髦的字符,并且由于铃声字符,扬声器有时会发出很多哔声。如果 stdout 从未到达实际打印的控制台 amd 而是被另一个进程捕获,那么它只是一个二进制流,就像任何其他具有与打开文件流相同的安全特性的二进制流。
        【解决方案5】:

        如果您选择适当的编码,您可以做到这一点,因为控制台是文本流。例如,对二进制数据使用Base64 编码,它将正常工作。另一种选择是“Quoted-printable”格式。当然,您最终会得到比原始二进制数据更多的字节,但恕我直言,这是使用控制台安全完成此操作的唯一方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-17
          • 2014-01-11
          • 1970-01-01
          • 2016-07-25
          • 2018-02-11
          • 1970-01-01
          • 1970-01-01
          • 2016-10-16
          相关资源
          最近更新 更多