【问题标题】:send and receive binary files properly using sockets c++使用套接字c ++正确发送和接收二进制文件
【发布时间】:2022-02-08 15:26:35
【问题描述】:

你好 stackflow 用户,

所以我想在 c++ 中使用套接字发送和接收我的二进制文件,这是我从服务器程序发送它的方式

send(Connections[conindex], reinterpret_cast<char*>(rawData), sizeof(rawData), NULL);

这是我的客户端程序接收它的方式

char raw[647680];
recv(Connection, raw, sizeof(raw), NULL);

还有比这更合适的方法吗?我想要这样我就不必每次都硬编码大小。 或任何其他替代品等

【问题讨论】:

  • 首先确保你在两边都以二进制模式打开文件。其次总是检查sendrecv返回什么。第三,切勿使用字符串函数(如strlen)来处理二进制数据。第四,如果您使用 TCP,请记住它是一个没有数据包边界的 streaming 协议,并且对 recv 的单个调用可能会收到 less 而不是在单个调用中传递给send,所以你总是需要循环调用recv
  • 最后,套接字和内核中的大多数内部缓冲区通常都不足以容纳整个大文件。在您的应用程序中使用较小的缓冲区,读取文件并逐个发送块,并且如上所述使用循环来接收和写入数据。
  • 好吧,我试试,谢谢!
  • @Someprogrammerdude 为什么以及如何检查 send 和 recv 的返回值?

标签: c++ sockets


【解决方案1】:

实现这一点的一种相当通用的方法(在 C 和 C++ 中)是这样的:

if (FILE *fp = fopen(filename, "rb"))
{
    size_t readBytes;
    char buffer[4096];
    while ((readBytes = fread(buffer, 1, sizeof(buffer), fp) > 0)
    {
        if (send(Connections[conindex], buffer, readBytes, 0) != readBytes)
        {
            handleErrors();
            break;
        }
    }
    close(Connections[conindex]);
}

在客户端:

if (FILE *fp = fopen(filename, "wb"))
{
    size_t readBytes;
    char buffer[4096];
    while ((readBytes = recv(socket, buffer, sizeof(buffer), 0) > 0)
    {
        if (fwrite(buffer, 1, readBytes, fp) != readBytes)
        {
            handleErrors();
            break;
        }
    }
}

这种类似 FTP 的连接方式的替代方案包括首先发送文件的大小,因此客户端将知道何时停止侦听而不是等待断开连接。

请注意,此代码未经测试,仅用于说明概念。

【讨论】:

  • 为什么在 C++ 程序中使用fopen 和相关函数?
  • 这里使用size_t时也要小心。 size_t 类型是 unsigned 整数,但 sendrecv 都返回 signed 整数。例如,如果recv 失败并返回-1,则比较(readBytes = recv(...)) &gt; 0 将无法按预期工作。
猜你喜欢
  • 1970-01-01
  • 2021-06-13
  • 2011-12-03
  • 1970-01-01
  • 2013-04-01
  • 2011-07-26
  • 2013-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多