Question

I have a class for an RDT Header that holds information for an implementation of several reliable data transfer protocols. I need to attach that information (a total of 12 bytes) to my send buffer to transfer it over the socket. I am trying to use memcpy to do this but for some reason it just leaves junk inside the buffer. Below is the line of code that isnt working. (RDT_HDR_SIZE is defined as 12).

Definition of variables that are passed to this function.

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

The function with memcpy that is having issues.

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

If i take out RDT_HDR_SIZE, the payload is assigned properly to buf, however it wipes out all my header fields. Any idea how to get this to work?

Thanks,

Eric R.

EDIT:

Here is the code for my RdtHeader class -- perhaps it will be of use.

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
}; 
Was it helpful?

Solution

This may be too obvious, but exactly how are you inspecting the buffer?

Have you tried

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

?

If you instead are doing ...

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

... then you should expect to see just garbage (with correct operation) since the win field acts as zero-terminator for the "string" that that latter call is printing.

Cheers & hth.,

– Alf

OTHER TIPS

As Mark said, look at sizeof(RdtHeader). There might be some padding inside the struct (especially since there is a long int there) that throws the calculations off.

But other than that, I don't see an obvious problem here. I would try to add some print-outs, if you're running it in an environment where that is feasible, or try a debugger. Possibly the real problem is elsewhere in your code.

memcpy(header + 1, payload, payload_size + 1);
return sizeof(*header) + payload_size + 1;
  • You're mysteriously returning an extra 1, suggesting the payload is a null-terminated string. You might want to copy that terminator, so it's included in the last memcpy parameter.
  • By using the header pointer to calculate the memcpy destination, you'll never have to cast if types change, in particular if you change the type of buf. You can rely on the fact that C++ allows X * to degrade to void * to avoid ugly casting.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top