【问题标题】:Receive Binary Data and Write (Socket Programming in C++)接收二进制数据并写入(C++ 中的套接字编程)
【发布时间】:2014-01-24 16:34:23
【问题描述】:

我已经创建了服务器和客户端进行通信。客户端发送图像的二进制数据,然后服务器接收它并写入文件。我在下面粘贴了必要的代码。

            std::stringstream binStr;

            bytes_received = recv(new_sd, &binStr, sizeof(binStr) ,0);
            std::cout << binStr << std::endl;

            char buff[1024*1024];
            std::string image;

            while (!binStr.eof())
            {
                binStr.read(buff, sizeof (buff));
                image.append(buff, binStr.gcount());
            }

            int id = 1;
            std::stringstream ss2;
            ss2 << id;
            std::string str2 = ss2.str();
            std::ofstream img(str2.c_str(),std::ios::binary);
            std::cout << image.c_str() << std::endl;
            img.write(image.c_str(), image.length());

此代码创建名称为 id 的文件,但它是一个空文件。我该如何解决?

【问题讨论】:

  • 你的问题是?
  • 抱歉忘记了问题:),添加到第一条消息中。

标签: c++ sockets tcp binary sstream


【解决方案1】:

您不能像您尝试的那样将recv() 转换为std::stringstream。您必须先将recv() 放入缓冲区,然后您可以将该数据复制到您的std::stringstream 中。但是,您仅将std::stringstream 用作将数据获取到buff 缓冲区,然后从那里到std::string 的中间体。您可以完全摆脱 std::stringstream,而将 recv() 直接删除为 buff。我什至会完全摆脱std::string,因为您并不真正需要它:

int id = 1;
std::stringstream ss2;
ss2 << id;
std::ofstream img(ss2.str().c_str(), std::ios::binary);

// 1MB is a lot to put on the stack, use the heap instead
std::vector<char> buff(1024*1024);
do
{
    bytes_received = recv(new_sd, &buff[0], buff.size(), 0);
    if (bytes_received < 0)
        break; // ERROR!

    if (bytes_received == 0)
        break; // DISCONNECT!

    for (int i = 0; i < bytes_received; ++i)
        std::cout << buff[i];
    std::cout << std::endl;

    img.write(&buff[0], bytes_received);

    // TODO: if reached the end of the image, stop here
}
while (true);

除非发送方在将图像数据发送给您后关闭连接,否则您需要一种方法来知道何时到达图像的末尾。发件人必须将图像数据长度发送给您,以便您知道何时停止阅读。

【讨论】:

  • 感谢您的帮助,但我不知道如何实现您的 TODO。我已经从客户端发送了“size_t imageSize”。
  • 我更改了写入部分并解决了问题。 img.write(&amp;buff[8], bytes_received); 用记事本打开图像文件,看到 8 个“/00”字符。不知道那些字符是怎么放在那里的。
  • 你为什么要做出这样的改变?那会破坏代码。它必须是&amp;buff[0]。至于 TODO,您是否正在创建发送图像数据的发送方?如果是这样,那么您需要在发送图像数据之前更新它以发送图像数据长度。否则,您需要确定发件人是如何执行此操作的。如果没有发送长度,则检测数据结束的唯一方法是关闭连接。
  • 我更改了 buff[0] 因为发送者(客户端)和接收者(服务器)中的图像不同。如果我用 vim(或记事本)打开图像,收到的图像有额外的 8 个/00 字符。然后我从 buff[8] 开始忽略这些字符。
  • 前 8 个字节可能很重要,否则发送者一开始就不会发送它们。如果您必须从第 8 个字节开始,那么您必须从 bytes_received 中减去 8,否则当您 write() 它时,您将读取超过 buff 边缘的 8 个字节,从而将随机数据写入您的文件(如果不会导致访问冲突错误)。
猜你喜欢
  • 2014-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多