Question

J'ai un problème quand mon client envoie des données struct à mon serveur. Mon client utilise Qt tcp et mes utilisations de serveur boost.asio. De mon côté serveur, je peux recevoir les données de tampon envoyées par le client, mais quand je jetai les données à mes données struct, je reçois des données struct illisible.

Ce sont les données de struct en question:

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

est le code dans mon serveur pour lire des données sur le socket client:

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

dans le 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

Voici le code dans mon client pour envoyer les données 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);
}
Était-ce utile?

La solution

QDataStream operator << est utilisé pour la sérialisation, et non d'écrire des données brutes telles quelles.
Par exemple des séquences d'octets sont envoyés par un « en-tête » 32-bits indiquant la taille de la séquence.

Et parce que vous êtes la coulée de la structure entière à char*, il l'interprète comme une chaîne et se termine au premier caractère '\0' qui est dans la partie int du struct.

Donc, vous devriez plutôt écrire les deux membres séparément et éviter la coulée explicite:

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

Le coup de pouce asio côté, puisque vous connaissez la taille de la structure, vous devez utiliser async_read au lieu de async_read_some parce que ce dernier retour pourrait avant que la structure entière a été reçue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top