将主机字节顺序转换为网络字节顺序有时会导致奇怪的结果



我目前正在用 c++ 编写一个服务器,供 android 客户端使用。基本上我使用 googles 协议缓冲区进行数据传输,在发送 protobuf 包之前,我按网络字节顺序发送包大小。这是我发送一个包裹的函数:

bool Client::sendOnePackage(const std::string & data) {
    int32_t packageSize = data.length();
    packageSize = htonl(packageSize);
    char packageSizeBuffer[sizeof (int32_t)];
    memcpy(packageSizeBuffer, &packageSize, sizeof (int32_t));
    if (send(con.sockfd, packageSizeBuffer, sizeof (int32_t), 0) == sizeof (int32_t)) {
        if (send(con.sockfd, data.c_str(), packageSize, 0) == packageSize) {
            return true;
        }
    }
    return false;
}

然后,android 部分将负责将发送的整数转换为主机字节顺序的包:

int answerLength = ByteBuffer.wrap(answerLengthData).getInt();

现在的问题是:当我通过网络发送大小为 8 的包裹时,它工作得很好,android 接收字节数组 0,0,0,8(始终为 4 个字节)。但是当我通过网络发送值 6 时,android 会收到奇数字节数组 0,114,0,0,这会导致一个奇怪的大包大小 (7471104)。

我在这里错过了什么吗?如果您需要更多信息或更多代码,请询问它,然后发布它。

你用 htonl() 的结果覆盖 packageSize 的值:

packageSize = htonl(packageSize);

然后你使用它作为传递给send()的包大小:

send(con.sockfd, data.c_str(), packageSize, 0)

将附加值保存在不同的变量中。并且不要使用临时字符缓冲区:

bool Client::sendOnePackage(const std::string & data) {
    int32_t packageSize = data.length();
    int32_t conv_size = htonl(packageSize);
    if (send(con.sockfd, reinterpret_cast<char*>(&conv_size), sizeof (int32_t), 0) == sizeof (int32_t)) {
        if (send(con.sockfd, data.c_str(), packageSize, 0) == packageSize) { //use original size
            return true;
        }
    }
    return false;
}

相关内容

最新更新