QT客户端发送结构数据以促进ASIO服务器
-
25-10-2019 - |
题
当我的客户端将结构数据发送到服务器时,我有问题。我的客户端使用QT TCP,我的服务器使用boost.asio。在我的服务器端,我可以接收客户端发送的缓冲区数据,但是当我将数据投放到结构数据时,我会得到一个无法阅读的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))
);
在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);
}
解决方案
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
因为后者可能会在收到整个结构之前返回。
不隶属于 StackOverflow