Message de
guitou :
Xfennec wrote:
- Pourquoi pas une structure, effectivement. Sur le même thème, je me suis souvent dit qu'il fallait fournir à l'utilisateur de Raydium des fonctions (toutes simples) pour "pusher" ses données dans un paquet et ainsi éviter les inesthétiques memcpy et décallages d'offset demandés à l'heure actuelle.
Bon avant tout, je vais proposer un truc mais ne crie pas si je dis des conneries ou si ça implique trop de changements autre part
![Smile :)](./images/smilies/icon_smile.gif)
En fait, j'envisageais une structure raydium_network_packet de ce genre là:
Code:
struct raydium_network_packet
{
unsigned int cur_read;
unsigned int tot_size;
/* Le paquet lui même */
unsigned char type;
unsigned char userid;
unsigned short tcpid;
char[RAYDIUM_NETWORK_DATA_SIZE] data;
}
Cette structure pourrait être allouée et remplie initialement avec une fonction raydium_network_new_pkt(unsigned char type, unsigned char userid, unsigned short tcpid). La taille du champ data est en fait RAYDIUM_NETWORK_PACKET_SIZE - la taille des champs type, userid et tcpid.
La structure serait ensuite manipulée avec raydium_network_write_data(struct raydium_network_packet * pkt, void * data, size_t size). Cette fonction irait écrire dans la partie data:
- en pkt->data+pkt->cur_read, on écrit la taille de la donnée qui va suivre
- en pkt->data+pkt->cur_read+sizeof(size_t), on écrit la donnée elle même
Enfin, on augmente l'index pkt->cur_read de la longueur écrite.
Il suffit ensuite de passer &pkt->type avec une longueur RAYDIUM_NETWORK_PACKET_SIZE à la fonction d'envoi dans la socket.
De l'autre coté, le packet est reçu, on initialise un paquet avec les données reçues. Puis raydium_network_read_data(struct raydium_network_packet * pkt, void * ptr, size_t * size) entre en jeu. Cette fonction va lire:
- en pkt->data+pkt->cur_read, la taille de la donnée qui doit être lue. Si cette taille est cohérente avec la taille des données encore à lire en se servant de pkt->cur_read et pkt->tot_size (i.e. pas de débordement), on va la mettre dans size (argument passé par référence)
- en pkt->data+pkt->cur_read+sizeof(size_t), la donnée elle même pour la mettre dans ptr (passé en argument).
Si tout s'est bien passé, l'index pkt->cur_read est augmenté de la taille lue.
Cette méthode est un peu lourde, on perd en charge utile également dans les paquets qu'on échange, on risque également de perdre en flexibilité de l'api (et j'entends presque des collègues hurler "asn1 !!"
![Smile :)](./images/smilies/icon_smile.gif)
).
Cependant, elle me semble la plus simple pour éviter des "petites horreurs" que j'ai vues (strcpy et strlen sur des données venant d'un paquet réseau, c'est maaal
![Smile :)](./images/smilies/icon_smile.gif)
).
Xfennec wrote:
- La taille fixe des paquets facilite (beaucoup) l'écriture de la couche réseau mais n'est pas foncièrement indispensable. Par contre le gain de perf avec des tailles variables risque d'être assez faible à mon avis (puisque on croise une majorité de paquets de données ODE sur le réseau en fait).
Je ne vois pas trop ce qui est facilité, à part le calcul de taille des données échangées. Avec la structure précédente, il suffirait de manipuler ->tot_size.