创建用于写入TCP套接字的消息

时间:2012-07-31 11:22:11

标签: c++ sockets tcp boost-asio

我真的不知道如何提出这个问题,但我们走了。

因此,假设我使用来自Boost libs的ASIO连接到使用TCP套接字的服务器并向其写入某个消息。

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

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

此时我真的很困惑。非常感谢。

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

一个。定义可以序列化的数据包结构。

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());

答案 2 :(得分: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 ) );