Frage

Ich habe ein Problem, wenn mein Client Strukturdaten an meinen Server sendet. Mein Client verwendet QT TCP und mein Server verwendet Boost.asio. Auf meiner Serverseite kann ich die vom Client gesendeten Pufferdaten empfangen, aber wenn ich die Daten in meine Strukturdaten werde, erhalte ich eine strukturelle Daten nicht lesbar.

Dies sind die fraglichen Strukturdaten:

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

Dies ist der Code in meinem Server, um Daten in der Client -Socket zu lesen:

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

im ClientManager :: HandleaD:

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

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

Dies ist der Code in meinem Client, um die Strukturdaten zu senden:

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);
}
War es hilfreich?

Lösung

QDataStream operator << wird für die Serialisierung verwendet und nicht wie es ist.
Zum Beispiel werden Byte -Sequenzen mit a gesendet 32-bits "Header", was die Größe der Sequenz angibt.

Und weil du die ganze Struktur auf die Struktur wirft char*, es interpretiert es als Zeichenfolge und stoppt bei der ersten '\0' Charakter, der in der ist int Teil der Struktur.

Sie sollten also lieber die beiden Mitglieder separat schreiben und explizites Casting vermeiden:

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

Auf Boost ASIO -Seite sollten Sie verwenden, da Sie die Größe der Struktur kennen, da Sie verwenden sollten async_read Anstatt von async_read_some Weil letztere möglicherweise zurückkehren, bevor die gesamte Struktur eingegangen ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top