QT -Client senden Sie eine Strukturdaten, um den ASIO -Server zu steigern
-
25-10-2019 - |
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);
}
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.