2012-05-20 2 views
1

Voici quelque chose sur lequel je travaille depuis un certain temps et que je ne peux pas résoudre pourquoi il ne fonctionne pas correctement, j'espère que vous pourrez m'aider à résoudre quelque chose! Je vais essayer d'être aussi descriptif que possible.Problèmes de sérialisation et de sérialisation dans ANSI C

L'idée est de sérialiser une structure (structure de paquets NIPC), d'envoyer via TCP à un autre processus, puis de désérialiser et de reconstruire cette structure. Mais d'une manière ou d'une autre je ne peux pas le faire fonctionner correctement, juste partiellement. Voici les structures.

typedef struct { 
    char pct_type; 
    short int payload_lenght; 
}__attribute__((__packed__)) t_header; 

typedef struct { 
    char* path; 
    long unsigned int size; 
    long int offset; 
}__attribute__ ((__packed__)) t_payload_read; 

typedef struct { 
    t_header header; 
    t_payload_read payload; 
}__attribute__ ((__packed__)) t_pct_read; 

Ensuite, je sérialisé la charge utile première (offset, la taille et le chemin), pour calculer la longueur de la charge utile, l'ensemble du paquet, y compris l'en-tête pour l'envoyer. Et puis Désérialisé, mais il n'y a aucun moyen de le faire fonctionner, de l'autre côté je reçois l'en-tête OK et le champ de chemin "OK", mais je reçois des nombres étranges sur offset et taille, par exemple, en utilisant ces valeurs codées Structure:

type: 4 
offset: 5 
size: 15 
path: ~/Desarrollo/Workspace 

je reçois:

pct->header.pct_type: 4 
pct->header.payload_length: 28 
pct->payload.path: ~/Desarrollo/Workspac 
pct->payload.size: 143994937 
pct->payload.offset: 143994941 

ici, j'ajouter les fonctions de sérialisation et désérialisation je CONÇU, j'ai essayé d'être aussi descriptif et minutieux que possible.

char* serialize_read(t_pct_read* packet) { 
    char* buffer = malloc(
      sizeof(t_header) + sizeof(packet->payload.offset) 
        + sizeof(packet->payload.size) 
        + strlen(packet->payload.path + 1)); 
    char* payload = malloc(
      sizeof(packet->payload.offset) + sizeof(packet->payload.size) 
        + strlen(packet->payload.path) + 1); 
    int offset; 

    // First I serialize the Payload, in order to calculate It's lenght 

    memcpy(payload, packet->payload.path, strlen(packet->payload.path) + 1); 

    offset = strlen(packet->payload.path)+1; 

    memcpy(payload + offset, &packet->payload.size, sizeof(long unsigned int)); 

    offset += (sizeof(long unsigned int)); 

    memcpy(payload + offset, &packet->payload.offset, sizeof(long int)); 

    packet->header.payload_lenght = offset+1; // Here I get payload's length 

    offset = 0; 

    // Same procedure here, but for the entire packet, including the header.  

    memcpy(buffer, &packet->header.pct_type, sizeof(char)); 

    offset = sizeof(char); 

    memcpy(buffer + offset, &packet->header.payload_lenght, sizeof(short int)); 

    offset += sizeof(short int); 

    memcpy(buffer + offset, packet->payload.path, 
      strlen(packet->payload.path) + 1); 

    offset += strlen(packet->payload.path + 1); 

    memcpy(buffer + offset, &packet->payload.size, sizeof(long unsigned int)); 

    offset += (sizeof(long unsigned int)); 

    memcpy(buffer + offset, &packet->payload.offset, sizeof(long int)); 

    return buffer; 

} 

t_pct_read* deserialize_read(char* stream) { 
    t_pct_read* packet = malloc(sizeof(t_pct_read)); 

    int offset; 
    int alloc_size; 

    memcpy(&packet->header.pct_type, stream, sizeof(char)); 

    offset = sizeof(char); 

    memcpy(&packet->header.payload_lenght, stream + offset, sizeof(short int)); 

    offset += sizeof(short int); 

    for (alloc_size = 1; (stream + offset)[alloc_size - 1] != '\0'; 
      alloc_size++) { 
     packet->payload.path = malloc(alloc_size)+1; 
    } 

    memcpy(packet->payload.path, stream + offset, alloc_size+1); 

    offset += strlen(packet->payload.path); 

    memcpy(&packet->payload.size, stream + offset, sizeof(long unsigned int)); 

    offset += (sizeof(long unsigned int)); 

    memcpy(&packet->payload.offset, stream + offset, sizeof(long int)); 

    return packet; 
} 

Répondre

0

strlen(packet->payload.path + 1) semble suspect, en particulier par rapport à strlen(packet->payload.path) + 1).
Etes-vous sûr que c'est ce que vous voulez dire?

+0

Merci, c'était clairement une erreur de mon côté, mais ça ne marche toujours pas, d'une certaine manière le chemin est toujours "~/Desarrollo/Workspac" sans le "e" final et je suspecte que c'est la désérialisation Je reçois ces chiffres sur "taille" et le décalage "Toutes les idées ?, merci encore pour votre aide mec! –

0

En mettant de côté les problèmes de style, vous avez une erreur d'un par un dans votre fonction de désérialisation. Au lieu de

offset += strlen(packet->payload.path); 

utilisation

offset += alloc_size+1 
+0

J'ai vérifié cela et vous avez raison, merci! Je reçois toujours les mêmes problèmes sur la sortie. On pense que je trouve confus, quand est le délimiteur '\ 0' placé? ou si je devrais l'ajouter à mon chemin manuellement? parce que j'ai codé en dur la valeur "chemin" de la structure de cette façon. pct_read-> payload.path = "~/Desarrollo/Workspace"; Et je ne sais pas comment ça se résout. Merci encore de m'avoir aidé! –

Questions connexes