我试图使用boost asio发送一组三个变量,一个64位整数和两个32位整数。我知道如何使用boost asio发送数据,但我正在努力将这三个变量转换成我可以使用boost asio发送的东西,任何想法?
我用于变量的类型如下:
boost::uint64_t
boost::uint32_t
boost::uint32_t
这样做的目的是将数据作为UDP跟踪器连接请求(Bittorrent协议)发送,其描述可在此处找到:http://www.bittorrent.org/beps/bep_0015.html#udp-tracker-protocol
Offset Size Name Value
0 64-bit integer connection_id 0x41727101980
8 32-bit integer action 0 // connect
12 32-bit integer transaction_id
16
答案 0 :(得分:3)
创建原始内存缓冲区。使用 endian-aware 复制函数将整数放在缓冲区中。发送缓冲区。
bittorrent协议使用什么字节序?它是大端,所以任何依赖于铸造的解决方案现在都不适用于典型的消费电子产品,因为它们在内存中使用小端格式。在创建要发送的缓冲区时,您还必须交换字节。
答案 1 :(得分:1)
好的,您正在尝试匹配已记录每个字段的预期字节偏移和字节顺序的现有网络协议。这是您想要使用uint8_t
的原始缓冲区的时间之一。您的代码应如下所示:
// This is *not* necessarily the same as sizeof(struct containing 1 uint64_t
// and 2 uint32_t).
#define BT_CONNECT_REQUEST_WIRE_LEN 16
// ...
uint8_t send_buf[BT_CONNECT_REQUEST_WIRE_LEN];
cpu_to_be64(connection_id, &send_buf[ 0]);
cpu_to_be32(0 /*action=connect*/, &send_buf[ 8]);
cpu_to_be32(transaction_id, &send_buf[12]);
// transmit 'send_buf' using boost::asio
cpu_to_be32
函数应如下所示:
void
cpu_to_be32(uint32_t n, uint8_t *dest)
{
dest[0] = uint8_t((n & 0xFF000000) >> 24);
dest[1] = uint8_t((n & 0x00FF0000) >> 16);
dest[2] = uint8_t((n & 0x0000FF00) >> 8);
dest[3] = uint8_t((n & 0x000000FF) >> 0);
}
反向(be32_to_cpu
)和模拟(cpu_to_be64
)留作练习。您可能还想尝试编写从第一个参数中推导出适当大小的模板函数,但我个人认为在函数名中明确指出大小会使这种代码更加自我记录。
答案 2 :(得分:0)
将结构转换为array
/ vector
/ string
很容易,可以通过boost::asio
发送。例如:
struct Type
{
boost::uint64_t v1;
boost::uint32_t v2;
boost::uint32_t v3;
}
Type t;
std::string str( reinterpret_cast<char*> (&t), sizeof(t) );
我不知道你的应用程序的架构,但也可以从内存创建asio :: buffer:
boost::asio::buffer( &t, sizeof(t) );
在这种情况下,您应该注意t
的生命周期。