QTクライアントはstructデータを送信してASIOサーバーをブーストします
-
25-10-2019 - |
質問
クライアントがStructデータをサーバーに送信したときに問題があります。クライアントはQT TCPを使用し、サーバーはboost.asioを使用します。サーバー側では、クライアントから送信されたバッファデータを受信できますが、データをstructデータにキャストすると、structデータがわかりません。
これは問題の構造データです。
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))
);
クライアントマネージャー:: Handleread:
ProtocoleCS *_proto; // this is the struct data i have to cast
_proto = static_cast<ProtocoleCS*>(static_cast<void*>(&_buffer));
// I can read _proto
これは私のクライアントのコードであり、structデータを送信します。
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);
}
解決
QDataStream operator <<
シリアル化には使用され、生データをそのまま記述しません。
たとえば、バイトシーケンスはaで送信されます 32-bits
シーケンスのサイズを示す「ヘッダー」。
そして、あなたが構造全体をキャストしているからです char*
, 、それはそれを文字列として解釈し、最初に停止します '\0'
にあるキャラクター int
構造体の一部。
したがって、2人のメンバーを個別に書いて、明示的なキャストを避ける必要があります。
// 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
後者は、構造全体が受信される前に戻る可能性があるためです。
所属していません StackOverflow