Клиент Qt отправляет данные структуры для повышения качества сервера asio - PullRequest
1 голос
/ 29 ноября 2011

У меня проблема, когда мой клиент отправляет данные структуры на мой сервер.Мой клиент использует Qt tcp, а мой сервер использует boost.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);
}

1 Ответ

2 голосов
/ 29 ноября 2011

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

Со стороны boost asio, поскольку вы знаете размер структуры, вы должны использовать async_read вместо async_read_some, поскольку последняя может вернуться до получения всей структуры.

...