boost :: asio与标准C套接字接口之间的协作

| 我目前正在做一个小项目:有一个协议可以通过使用标准C接口实现的UDP发送一些字符串。 尽管它工作得很好,但我想用一些更复杂的C ++重写它(考虑它可以练习)。 当前它是这样的:客户端需要该字符串,因此它发送以下“ 0”:
struct request {
  uint8_t msg_type;// == 1
  uint64_t key; // generated randomly to identify each request
}
在新的实现中,我想使用
boost::asio
,因此在服务器中,我有以下代码:
boost::asio::io_service io_service;
boost::asio::ip::udp::endpoint client_endpoint;
boost::asio::ip::udp::socket socket(io_service,
        boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(),
        m_serverPort));
boost::asio::streambuf sb;
boost::asio::streambuf::mutable_buffers_type mutableBuf =
        sb.prepare(sizeof(request));
size_t received_bytes = socket.receive_from(mutableBuf, client_endpoint);
sb.commit(received_bytes);

request r;
std::istream is(&sb);
is >> msg_type;
is >> key;
key = __bswap64(key); // I\'m using network byteorder for numbers sent with this protocol
                      // and there\'s no ntohll function on Snow Leopard (at least I can\'t
                      // find one)
sb.consume(received_bytes);
这是我的问题:我尝试以此方式接收的\“ key \”值是错误的-我的意思是我收到了一些我没有发送的东西。 这是我的怀疑: __bswap64不能将网络转换为主机(小尾数)字节顺序 我误解了如何将boost :: asio :: streambuf与流一起使用 旧的C接口和boost之间存在一些不兼容(但我不这么认为) 因为我发现boost函数只是它的包装器) 编辑: 嗯,他们说:“直到你克服之后,才称赞福特。”现在,我在代码的另一个地方也遇到了非常类似的问题。我有以下结构,作为上面提到的请求的回复发送:
struct __attribute__ ((packed)) CITE_MSG_T
{
        uint8_t msg_id;
        uint64_t key; // must be the same as in request
        uint16_t index; // part number
        uint16_t parts; // number of all parts
    CITE_PART_T text; // message being sent
};

//where CITE_PART_T is:
struct __attribute__ ((packed)) CITE_PART_T
{ 
        uint16_t data_length;
        char* data;
};
以及以下代码:http://pastebin.com/eTzq6AWQ。 不幸的是,里面还有另一个错误,我又读了一些我没有发送的东西-尽管旧的实现说例如3和10,但是replyMsg.parts和ReplyMsg.index总是为0。这次?如您所见,我负责填充,并且使用read代替operator >>。如果您想知道为什么我逐个字段读取该结构,这是一个答案:服务器发送两种不同的结构,两种结构都以msg_id开头,一种是成功的,另一种是失败的。现在,我根本不知道该怎么做。     
已邀请:
        您正在使用格式化的输入,就好像发送的数据是文本数据一样-您需要未格式化的输入。了解
std::istream::read
成员函数,因为它应该是您所用的而不是
operator>>
。 请注意,如果您在每次提取后都检查了流的状态,这将立即显而易见,因为在非抛出代码中总是应该如此。     
        您忘记了填充。您的请求结构可能在第一个成员和第二个成员之间至少有三个字节由编译器插入,如下所示:
struct request {
    uint8_t msg_type;
    char __pad__[3]; // or 7 on 64-bit machine.
    uint64_t key;
};
您可以使用属性来解决此问题(例如在GCC中)(请参见GCC手册):
struct __attribute__ ((__packed__)) request { ...
是的,我确实错过了您尝试读取文本而不是二进制文件的事实。请先解决此问题,然后再通过对齐/填充进行咬合:)     

要回复问题请先登录注册