【问题标题】:Send std::stringstream in named pipe在命名管道中发送 std::stringstream
【发布时间】:2020-05-27 17:03:08
【问题描述】:

我有一个 std::stringstream 类型的变量,我在其中以 blob 格式写入数据,之后我想将其发送到管道,从这里数据被另一个应用程序接管并通过 tcp 套接字发送。当我调用 std::stringstream.str() 时,它会向我显示正确的信息。如果我给 std::cout

std::stringstream stream;
int fd;
const char* fifo = "/tmp/adpluspipe";

/* create the FIFO (named pipe) */
mkfifo(fifo, 0666);

/* write data to the FIFO */
fd = open(fifo, O_WRONLY);
write(fd, stream.str().data(), 84);
close(fd);

/* remove the FIFO */
unlink(fifo);

流变量的内容就是图片中的那个: content of the stream variable

我通过套接字接收一串字节,根据加密文档对该内容进行解码,应用一些过滤器,然后仅使用我需要的数据对其进行编码。它有很多带有'\0' 的区域,因为最终它必须具有相同的长度,以便在应用解码文档时它可以工作。代码很大很复杂,所以我无法显示它。该编码内容看起来像图片中的内容,我必须通过管道将其发送到另一个应用程序。我使用了std::stringstream,因为在这里我可以根据加密文档逐字节添加。 该变量中的写入代码是:

// The data is added like this:
int value = std::bitset<8>("00111101").to_ulong();
// or
int value = 80;
// and so on



void writeBytes(std::stringstream &stream, int value, int valueSize)
{
    unsigned char bytes[valueSize];

    if(valueSize == 1){
        bytes[0] = value & 0xFF;
    }

    if(valueSize == 2){
        bytes[0] = (value >> 8) & 0xFF;
        bytes[1] = value & 0xFF;
    }

    if(valueSize == 4){
        bytes[0] = (value >> 24) & 0xFF;
        bytes[1] = (value >> 16) & 0xFF;
        bytes[2] = (value >> 8) & 0xFF;
        bytes[3] = value & 0xFF;
    }

    stream.write(reinterpret_cast<char*>(&bytes), sizeof(bytes));

    memset(bytes, 0, sizeof(bytes));

}

【问题讨论】:

  • 请不要发布指向文本图像的链接。请在您的问题中将文本作为文本发布。流变量的内容是图像中显示的文本吗?或者,当使用流变量的内容进行管道传输时,图像是否表示执行 hexdump 或类似程序的结果文本?
  • 您没有在管道中写入任何内容,而读者应该是制造和破坏 fifo 的人。如果您取消链接 fifo,作者应该如何阅读?
  • 图像包含流变量的内容。我想通过管道发送该内容,然后可以对其进行解码。如果我在流变量中放置一个字符串而不是那个内容,然后通过管道发送它,我可以毫无问题地读取该文本。
  • 也请提供Minimal, Reproducable Example。否则,我们通常无法帮助您。

标签: c++


【解决方案1】:

当你这样做时:

std::cout << std::stringstream.str().c_str();

它试图将数据解释为 C 字符串,从图像中我可以看出它显然不是 C 字符串,因为它在很多地方都有空字符 '\0'。每个处理 C 字符串的 C++ 函数都期望字符串以'\0' 终止,因此它一看到空字符就停止处理。当您使用std::string(由.str() 返回)时,这不是问题,因为它存储字符串的大小,并且不依赖空字符作为终止符。对于std::string'\0' 并不特殊。

至于为什么在接收端看不到内容,我只能推测,因为您没有提供代码,但我假设您将数据作为 C 字符串处理(const char *) ,不是吗?

【讨论】:

  • 我在下面添加了更多详细信息。谢谢
  • @Cristian 我已经阅读了您发布的详细信息,但我不清楚我们还能为您提供什么帮助。我看到您已经使用stream.str().data() 来获取数据,只要您使用正确的大小(顺便说一句,您可以为此使用字符串的.size()),它应该可以工作。
  • 不幸的是,stream.str().data ()stream.str().c_str() 都返回 null,并且不会在管道中发送任何内容。在cout &lt;&lt; stream.str() 返回正确的字符串和其他null
  • stream.str().data() 的返回值肯定不为空,否则会出现分段错误。它是一个指向缓冲区开始的指针,来自该指针的 84 个字节肯定由write() 写入 FIFO。为什么你不能收到它,就像我说的,我不知道是因为你没有分享代码。但 Bailey Kocin 的评论可能是正确的,因为您在接收程序有机会打开它之前用 unlink() 擦除了 FIFO。
  • write() 不是需要 C 字符串的函数之一。相反,它会处理您告诉它的字节数,在本例中为 84。字节中的值是否为'\0' 无关紧要。另一方面,std::cout&lt;&lt; 在您输入 char * 时确实需要一个 C 字符串,并且会在第一个 '\0' 处停止。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 2015-05-10
相关资源
最近更新 更多