Question

I am trying to send my struct over a UDP socket.

struct Packet { int seqnum; char data[BUFFERSIZE]; };

So on the sender I have

bytes = sizeof(packet);
char sending[bytes];
bzero(sending, bytes);
memcpy((void *) sending, (void *) &packet, sizeof(bytes));
bytes = sendto(sockfd, sending, sizeof(sending), 0,
    (struct sockaddr *) &client, clientSize);

So I'm hoping that copies my struct into the Char[].

On the receiver I have

int bytes;
bytes = sizeof(struct Packet);
char recv[bytes];
bytes = recvfrom(sockfd, recv, bytes, 0,
    (struct sockaddr *) &client, &clientSize);
memcpy((void *) currentpkt, (void *) recv, bytes);

However on the receiver with memcpy((void *) currentpkt, (void *) recv, bytes); I get an error:

error: cannot convert to a pointer type

What am I doing wrong? Is there a better way to send my struct over a UDP socket?

***** UPDATE *****

Thanks for the answers everyone. In the end I missed the '&' but my code now looks like this.

Sender:

void udt_send(struct Packet packet) {
    int bytes;
    bytes = sendto(sockfd, (char *) &packet, sizeof(packet), 0,
            (struct sockaddr *) &client, clientSize);
}

Receiver:

bytes = recvfrom(sockfd, (char *) &currentpkt, bytes, 0,
        (struct sockaddr *) &client, &clientSize);

In C its nice that we can just cast it to a char and send the bytes over.

Was it helpful?

Solution

currentpkt is of struct type; you need to get a pointer to the struct to get this to work:

memcpy(&currentpkt, recv, bytes);

For your second question, you have some other problems. What if you receive more bytes in a packet than sizeof(struct Packet)? As it's written now, you'll overrun your struct.

What if the client and server applications are compiled using different compilers or settings, or on platforms with different endianness? In this case, the struct might be different sizes on the two platforms and may be laid out in memory differently.

OTHER TIPS

So I'm thinking that currentpkt is a struct Packet, and that you really meant to say &currentpkt.

I might also note that memcpy() already has void * parameters, so the (void *) casts are not needed.

memcpy((void *) currentpkt, (void *) recv, bytes);

Your error message indicates a cast problem. recv is ok since it's a char[] (no problem converting to (void*)). The problem must be that currentpkt must not be a pointer type.

It's not declared in your snippet so I don't know what it is, but I'd start there.

Doing memcpy from an entire struct is truly evil :-). First of all the data might be aligned differently depending on architecture. What if the architecture is different on the other side? Also using keywords such as __packed isn't portable between different compilers.

The best, as I know, is to use an API like the PHP pack/unpack. This makes the code truly portable without using compiler specific ugly keywords such as __packed.

I didn't find any pack/unpack for C on the net so I wrote my own.

For example to unpack two words from binary data:

   pbuf_unpack(p_bts, "ww", &hdr, &ver); 

Where

   p_bts is binary data
   "ww" describes the data structure
   hdr and ver is where to put the datause an API like the PHP pack/unpack. 

Another more extensive example:

   pbuf_unpack(p_entry, "bbbbbbbbww",
      &atrb_mbr.def_boot_par, &atrb_mbr.head_start, &atrb_mbr.sec_start,
      &atrb_mbr.cyl_start, &atrb_mbr.type, &atrb_mbr.head_end, 
      &atrb_mbr.sec_end, &atrb_mbr.cyl_end, &atrb_mbr.start_sec_pbr,
      &atrb_mbr.sec_per_par);

Packing is very easy:

   pbuf_pack(boot_buf, "sdsdhbhbhhbhhhwwbbbwsdsd", sizeof(fat_jmp_boot_t), 
      boot.jmp, sizeof(fat_oem_nm_t), boot.oem_nm, boot.n_bps, boot.n_spc, 
      boot.n_rs, boot.n_fs, boot.n_rde, boot.n_ts16, boot.media_des, 
      boot.n_fatsz16, boot.n_spt, boot.n_hds, boot.n_hs, boot.n_ts32, 
      boot.drv_no, boot.rsrvd1, boot.boot_sig, boot.vol_id, 
      sizeof(fat_vol_lbl_t), boot.lbl, sizeof(fat_vol_type_t), boot.type);

Not only does it create portable code but it's also beautiful;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top