0

我真的不知道如何提出这个问题,但我们开始吧。

所以让我们假设我正在使用 Boost 库中的 ASIO 来使用 TCP 套接字连接到服务器并向其写入特定消息。

该消息包含一些用户数据,如下所示:1 个字节(数据包 ID)、4 个字节(整数)、用户以 null 结尾的字符串和 6 个零字节(由服务器保留但未使用)。

组装这样的消息以与 ASIO 的 boost::asio::buffer 函数一起使用的最方便的方法是什么?

在这一点上我真的很困惑。非常感谢帮助。

4

3 回答 3

2

asio::buffer()您可以将结构调整为缓冲区序列,而不是使用函数制作单个缓冲区- asio 函数接受这样的概念。以这种方式发送固定--null-terminated--null-terminated-fixed-fixed-etc 之类的模式会很方便...

于 2012-07-31T11:44:30.630 回答
1

A. 定义可以序列化的数据包结构。

class ISerializable
{
public:
    virtual ~ISerializable(){}

    virtual void serialize(std::ostream& stream) = 0;
};

class LoginPacket : public ISerializable
{
public:
    // Constructor and access functions

    virtual void serialize(std::ostream& stream)
    {
        stream.write((const char*)&packetId, 1);
        stream.write((const char*)&accountId, 4);
        stream.write(username.c_str(), username.size() + 1);
        // Write the unused 6-bytes of zero
        int zero(0);
        stream.write((const char*)&zero, 4);
        stream.write((const char*)&zero, 2);
    }

private:
    unsigned char packetId;
    unsigned int32_t accountId;
    std::string username;
};

B. 现在,要使用这个数据包类,请执行以下操作:

LoginPacket packet;
// Fill details for the packet
std::stringstream data;
packet.serialize(data);
// Send the data to the network
yourSocket.send(data.str().c_str(), data.str().size());
于 2012-07-31T11:35:28.557 回答
1

boost::asio::buffer() 函数将其他类型的缓冲区调整或转换为 asio 使用的缓冲区。

您应该使用某种应用程序缓冲区,填充该缓冲区,然后将缓冲区传递给 asio 以写入线路。例如:

std::vector< char > data;

data.push_back( id );
data.push_back( i & 0xff );
data.push_back( ( i >> 8 ) & 0xff );
data.push_back( ( i >> 16 ) & 0xff );
data.push_back( ( i >> 24 ) & 0xff );

const char* const str = s.c_str();
data.insert( data.end(), str, str + std::strlen( str ) );

for ( int pad = 0; pad != 4; ++pad )
    data.push_back( 0 );

boost::asio::write( socket, boost::asio::buffer( data ) );
于 2012-07-31T11:56:56.297 回答