2010-10-12 4 views
3

J'ai une classe pour un en-tête RDT qui contient des informations pour une implémentation de plusieurs protocoles de transfert de données fiables. J'ai besoin de joindre cette information (un total de 12 octets) à mon tampon d'envoi pour le transférer sur le socket. J'essaye d'employer le memcpy pour faire ceci mais pour une raison quelconque il laisse juste la camelote à l'intérieur du tampon. Voici la ligne de code qui ne fonctionne pas. (RDT_HDR_SIZE est défini comme 12).Pourquoi le memcpy ne fonctionne-t-il pas correctement?

Définition des variables transmises à cette fonction.

char payload[] = "sample code sample code"; 
int payload_size = sizeof(payload) ; 
int pktsize = payload_size + sizeof(RdtHeader)+1 ; // 1 byte for NULL-terminated 
char * send_buf = new char[pktsize]; 

Fonction avec memcpy qui rencontre des problèmes.

unsigned int Sender::CreateSegment(char * buf, 
     char payload[], int payload_size, unsigned long seqnum) { 
    RdtHeader * header = (RdtHeader *) buf; 
    // set rdt fields: 
    header->ack = 0; 
    header->fin = 0; 
    header->ok = 0; 
    header->seq = seqnum; 
    header->win = 0; 
    header->syn = 0; 
    memcpy(buf+RDT_HDR_SIZE, payload, payload_size); 

    return (payload_size + RDT_HDR_SIZE + 1); 
} 

Si je sors RDT_HDR_SIZE, la charge utile est correctement attribuée à BUF, mais il efface tous mes champs d'en-tête. Une idée de comment faire fonctionner ça?

Merci,

Eric R.

EDIT:

Voici le code de ma classe RdtHeader - ce sera peut-être utile.

class RdtHeader{ // 12-byte header 
public: 
//1-byte flags field 
    u_char protocol:2;  // 2 bits: protocol type = 0 for RDT3, 1 for GBN, and 2 for STCP  
    u_char syn:1;   // 1 bit: SYN = 1 for connection setup 
    u_char fin:1;   // 1 bit: FIN = 1 for termination 
    u_char ok:1;   // 1 bit: OK = 1 receiver agrees, SYN_OK or FIN_OK 
    u_char reserved:3;  // 3 bits: unused 

    u_char unused;   // 1-byte unused filed; 

    u_short win;   // 2-byte receiver window size (the number of packets) 
    u_long seq;    // 4-byte sequence number 
    u_long ack;    // 4-byte ack number 
}; 
+0

Avez-vous essayé d'utiliser sizeof (RdtHeader) plutôt que coder en dur la taille du tampon? –

Répondre

2

Cela peut être trop évident, mais exactement comment inspectez-vous le tampon?

Avez-vous essayé

printf("%s\n", send_buf + sizeof(RdtHeader)); 

?

Si vous faites ... sont plutôt

printf("%s\n", send_buf); 

... alors vous devriez attendre de voir à ordures (avec un fonctionnement correct) étant donné que les actes sur le terrain win comme zéro de terminaison pour la « chaîne "que ce dernier appel imprime.

Vive & HTH,

-. Alf

+1

/facepalm --- Ok, donc la morale de l'histoire est que techniquement je lui ai donné un terminateur null lors de l'attribution de valeurs à mon RdtHeader. Merci d'avoir signalé cela. Je n'arrivais pas à comprendre pourquoi mon memcpy ne fonctionnait pas quand j'ai senti que ça aurait dû aller. Occains Rasoir ... Ce n'était pas la copie, mais comment je voyais ce qui avait été copié. –

2

Comme l'a dit Mark, regardez sizeof (RdtHeader). Il y a peut-être un peu de remplissage à l'intérieur de la structure (d'autant plus qu'il y a un long int), ce qui désactive les calculs.

Mais à part ça, je ne vois pas de problème évident ici. J'essaierais d'ajouter quelques impressions, si vous l'utilisez dans un environnement où c'est faisable, ou essayez un débogueur. Peut-être que le vrai problème est ailleurs dans votre code.

+0

J'ai essayé memcpy (buf + sizeof (RdtHeader), payload, payload_size) et ne copie toujours pas. Il laisse juste des déchets dans le tampon. J'ai placé un printf juste après le memcpy et n'a pas la charge utile dedans. J'ai modifié le message original et ajouté ma définition de classe pour RdtHeader –

0
memcpy(header + 1, payload, payload_size + 1); 
return sizeof(*header) + payload_size + 1; 
  • Vous êtes de retour mystérieusement un 1 supplémentaire, ce qui suggère la charge utile est une chaîne terminée par zéro. Vous pouvez vouloir copier ce terminateur, il est donc inclus dans le dernier paramètre memcpy .
  • En utilisant le pointeur header pour calculer la destination memcpy, vous n'aurez jamais à lancer si les types changent, en particulier si vous modifiez le type de buf. Vous pouvez compter sur le fait que C++ permet X * de se dégrader à void * pour éviter la coulée laide.
+0

Pas 100% sûr de ce que vous entendez par là. En utilisant le code que vous avez fourni, il n'y a pas de changement dans la sortie. Mon tampon reste juste indésirable. Si je supprime l'addition sur les pointeurs dans memcpy (que ce soit en utilisant l'en-tête, ou buf), la charge utile est bien copiée, mais je perds toutes mes informations d'en-tête. –

Questions connexes