其他分享
首页 > 其他分享> > c – 将数据转换为big endian

c – 将数据转换为big endian

作者:互联网

我正在使用WinSock将UDP数据包发送到服务器,我需要以big endian发送数据.我不确定如何在发送之前转换结构的字节顺序.

我有这样的结构:

struct ConnectIn
{
    std::int64_t ConnectionID = 0x41727101980;
    std::int32_t Action = 0;
    std::int32_t TransactionID;

    ConnectIn(std::int32_t transactionID)
    {
        TransactionID = transactionID;
    }
};

此刻我发送的内容如下:

ConnectIn msg(123);
int len = sizeof(msg);
int bytesSent = sendto(s, (char*)&msg, len, 0, (SOCKADDR*)&dest, sizeof(address));

如何在发送之前将msg的字节顺序转换为big endian?

如果你很好奇,我发送的数据是Bit Torrent UDP tracker protocol.

解决方法:

如果您想手动执行此操作,那么您所做的就是单独交换每个成员.您将成员从主机的字节顺序转换为网络的字节顺序.在Win32上,htonll()用于64位整数,而htonl()用于32位整数:

#include <Winsock2.h>

ConnectIn msg(123);

msg.ConnectionID = htonll(msg.ConnectionID);
msg.Action = htonl(msg.Action);
msg.TransactionID= htonl(msg.TransactionID);

然后,您可能还希望单独发送成员,以避免依赖主机系统的结构布局. Windows ABI不会在此结构中插入任何填充,但也许对于您使用它的某些其他结构.所以这是基本的想法:

char buf[sizeof msg.ConnectionID + sizeof msg.Action + sizeof msg.TransactionID];
char *bufi = buf;

std::memcpy(bufi, &msg.ConnectionID, sizeof msg.ConnectionID);
bufi += sizeof msg.ConnectionID;
std::memcpy(bufi, &msg.Action, sizeof msg.Action);
bufi += sizeof msg.Action;
std::memcpy(bufi, &msg.TransactionID, sizeof msg.TransactionID);
bufi += sizeof msg.TransactionID;

int len = sizeof buf;
int bytesSent = sendto(s, buf, len, 0, (SOCKADDR*)&dest, sizeof(address));

然后在接收端使用适当的ntoh *()函数,用于64位和32位类型,以便从网络的字节顺序转换为接收主机的字节顺序.

标签:bittorrent,c,endianness,winsock2
来源: https://codeday.me/bug/20190824/1713173.html