2011-11-29 79 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

相關問題