1

我正在尝试使用 boost asio 发送一组三个变量,一个 64 位整数和两个 32 位整数。我知道如何使用 boost asio 发送数据,但我正在努力将这三个变量转换为我可以使用 boost asio 发送的东西,有什么想法吗?

我用于变量的类型如下:

boost::uint64_t
boost::uint32_t
boost::uint32_t

这样做的目的是将数据作为 UDP Tracker Connect Request(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
4

3 回答 3

3

创建一个原始内存缓冲区。使用字节序感知复制函数将整数放置在缓冲区中。发送缓冲区。

bittorrent 协议使用什么字节序?它是大端的,所以现在任何依赖于转换的解决方案都不适用于典型的消费电子产品,因为它们在内存中使用小端格式。因此,在创建要发送的缓冲区时,您还必须交换字节。

于 2013-09-17T15:52:48.423 回答
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) 留作练习。您可能还想尝试编写从第一个参数中推断出适当大小的模板函数,但我个人认为在函数名称中明确指示大小会使这种代码更具自我记录性。

于 2013-09-17T16:01:53.210 回答
0

将结构转换为array//可以很容易地通过vector. 例如:stringboost::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.

于 2013-09-17T15:46:42.433 回答