Question

Pour une application en réseau, la façon dont nous avons la transmission de données dynamique est par memcpying une struct dans un (void *). Cela pose des problèmes, comme quand cela se fait à un std :: string. Les chaînes peuvent être de longueur dynamique, alors comment se l'autre côté savoir quand la fin de chaîne? Une idée que j'avais été d'utiliser quelque chose similaire à DataOuputStream de Java, où je pouvais passer que les variables qui à lui et il pourrait alors être mis dans un (void *). Si cela ne peut pas être fait, sa fraîcheur. Je n'aime tout simplement pas vraiment memcpying un struct. Quelque chose à ce sujet ne semble pas tout à fait raison.

Merci,
Robbie

Était-ce utile?

La solution

rien de mal à memcpy sur une struct - comme lng que le struct est rempli de tampons de taille fixe. Mettez là une variable dynamique et vous devez serialise différemment.

Si vous avez une struct avec std :: cordes là-dedans, créer un opérateur de flux et de l'utiliser pour formater un tampon. Vous pouvez ensuite memcpy que le tampon au transport de données. Si vous avez coup de pouce, utilisez Boost :: serialize qui fait tout cela pour vous (ce lien a également des liens vers libs sérialisation alternatives)

Notes: la manière habituelle de passer un tampon de taille variable est de commencer par l'envoi de la longueur, puis que le nombre d'octets de données. De temps en temps vous voyez des données transférées jusqu'à ce qu'un séparateur est reçu (et les champs dans les données sont elles-mêmes délimitées par un autre caractère, par exemple une virgule).

Autres conseils

Je vois deux parties de cette question:  - sérialisation des données sur un réseau  - faire passer les structures dans une pile de réseau

Pour sérialiser données sur un réseau, vous aurez besoin d'un protocole. Ne doit pas être difficile; pour ASCII même un cr / lf comme fin de paquet peut faire. Si vous utilisez un cadre (comme MFC), il peut fournir des fonctions de sérialisation pour vous; dans ce cas, vous devez vous soucier de la façon d'envoyer ce dans des paquets. Un qui fonctionne souvent packetization bien pour moi est:

<length><data_type>[data....][checksum]

Dans ce cas, la somme de contrôle est facultative, et également à zéro des données est possible, par exemple si le signal est transporté dans le data_type (à savoir Ack pour acklnowedgement)

Si vous travaillez sur le memcpy avec des structures, vous devrez considérer que Memcpy ne fait qu'une copie superficielle. Un pointeur est sans valeur une fois transmis sur un réseau; INSTAND vous devez transmettre les données de ce pointeur (à savoir le contenu de votre exemple de chaîne)

Pour l'envoi de données dynamiques à travers le réseau, vous disposez des options suivantes.

La première option dans le même paquet.

void SendData()
{
   int size;
   char payload[256];

   Send(messageType)
   Send(size);
   Send(payload)
}

Deuxième possibilité:

void SendData()
{
   char payload[256];

   Send(messageType)
   Send(payload)
}

Bien que dans les deux cas, vous serez confronté à plus d'un choix de conception. Dans le premier exemple vous envoyer le type de message et la taille de la charge utile et aussi alors la charge utile.

La deuxième option vous est que vous pouvez envoyer le type de message et vous pouvez envoyer la chaîne qui a un délimiteur de terminaison nulle.

Bien que ces deux options ne couvre pas complètement le problème de votre face, je pense. Tout d'abord, vous devez déterminer si vous construisez un jeu quel type de protocal vous utiliserez, UDP? TCP? Le deuxième problème, vous serez face à la taille maximale des paquets. Ensuite, au-dessus de ce que vous devez avoir le cadre en place afin que vous puissiez calculer la taille optimum du paquet qui ne sera pas perdu et fragmenté à l'inter web. Après cela, vous avez le contrôle de la bande passante en ce qui concerne la quantité de données que vous pouvez transmettre et recevoir entre le client et le serveur.

Par exemple, la façon dont la plupart des jeux abordent cette situation est chaque paquet est identifié avec ce qui suit.

MessageType
MessageSize
CRCCheckSum
MessageID
void buffer[payload]

Dans la situation où vous devez envoyer des données dynamiques vous envoyer une série de paquets non seulement un. Par exemple, si vous deviez envoyer un fichier accross le réseau la meilleure option serait d'utiliser TCP / IP parce que son protocal en streaming et garnentees que le flux complet arrive safly à l'autre extrémité. D'autre part UDP est un protocal à base de paquets et est ne pas faire de vérification que tous les paquets sont arrivés dans l'ordre ou du tout à l'autre bout.

Donc, en conclusion.

  1. Pour les données dynamiques, envoyer plusieurs paquets, mais avec un drapeau spécial dire plus de données est d'arriver à remplir ce message.
  2. Restez simple et si votre travail avec C ++ DonT prendre le paquet ou les données contiendra un terminateur nul et vérifier la taille par rapport à la charge utile si vous décidez d'utiliser une terminaison nulle.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top