2011-11-29 80 views
1

当我的客户端向我的服务器发送结构数据时遇到问题。 我的客户使用Qt tcp,我的服务器使用boost.asio。在我的服务器端,我可以接收客户端发送的缓冲区数据,但是当我将数据转换为我的结构数据时,我得到的结构数据不可读。Qt客户端发送一个结构数据来提升asio服务器

这是有问题的结构数据:

struct Protocole 
{ 
    int type; 
    char infos[1024]; 
} 

这是我的服务器的代码读取客户端套接字上的数据:

this->_socket.async_read_some(boost::asio::buffer(_buffer), // _buffer is type of char[1024]; 
    _strand.wrap(boost::bind(&ClientManager::HandleRead, 
    this, 
    boost::asio::placeholders::error, 
    boost::asio::placeholders::bytes_transferred)) 
    ); 
在ClientManager :: HandleRead

ProtocoleCS *_proto; // this is the struct data i have to cast 

_proto = static_cast<ProtocoleCS*>(static_cast<void*>(&_buffer)); 
// I can read _proto 

这是我的客户端发送结构数据的代码:

void    Network::SendMsgToServer() 
{ 
    QByteArray  block; 
    QDataStream  out(&block, QIODevice::WriteOnly); 
    out.setVersion(QDataStream::Qt_4_7); 
    Protocole  proto; 

    proto.type = 1; 

    std::cout << " i am sending a message" << std::endl; 

    proto._infos[0] = 'H'; 
    proto._infos[1] = 'E'; 
    proto._infos[2] = 'L'; 
    proto._infos[3] = 'L'; 
    proto._infos[4] = 'O'; 
    proto._id[5] = '\0'; 

    out << static_cast<char*>(static_cast<void*>(&proto)); 
    this->socket->write(block); 
} 

回答

2

QDataStream operator <<用于序列化,而不是原样写入原始数据。
例如,字节序列与32-bits“头部”一起发送,指示序列的大小。

因为你是铸造整个结构char*,它解释为一个字符串,并在第一'\0'字符是在结构的int部分停止。

所以,你应该相当的两位成员分开来写,避免显式类型转换:

// If you want to avoid endianness swapping on boost asio side 
// and if both the server and the client use the same endianness 
out.setByteOrder(QDataStream::ByteOrder(QSysInfo::ByteOrder)); 

out << proto.type; 
out.writeRawData(proto.infos, sizeof(proto.infos)); 

升压ASIO的一面,因为你知道该结构的大小,你应该使用async_read,而不是async_read_some因为后者可能在收到整个结构之前返回。

+0

这解决了我的问题非常感谢你 – RottenRonin

相关问题