Reputation: 13
I have a very specific question on socket programming. My code is similar to the following.
struct data_packet{
unsigned char seqnumber;
char data[500];
}
struct data_packet packettosend;
packettosend.seqnumber = '0'
packettosend.data = 'some binary data' (this could be any length from 0 bytes to 500 bytes)
//sender code
char buffer[501];
memcpy(buffer, &packettosend, sizeof(packetosend));
int s = sendto(socketfd, buffer, sizeof(buffer), 0 , .......other params);
//receiver code
char recvbuffer[501];
int t = recvfrom(recvsocketdf, recvbuffer, 501, 0 ....other params);
How do I set up my receiver to receive the data and save it on a `struct data_packet`?
The seqnumber is a 1-byte char, and data could be 0 byte to 500 bytes.
I am using sendto
to send the buffer and recvfrom
to receive the buffer on the other end.
How do I receive my seqnumber and data on the receiving end? I am very new to C and Socket programming. I appreciate any help.
Upvotes: 1
Views: 2236
Reputation:
I concur with Dennis Afanasev. To elaborate on the casting strategy, read all 501 bytes (including partial/incomplete reads) then cast into the pointer variable e.g.:
struct data_packet *dataRecv = (struct data_packet *)&recvbuffer[0];
Then you can dereference dataRecv to access the struct, as in dataRecv->seqnumber and dataRecv->data.
Upvotes: 0
Reputation: 153328
Possible problem:
Code likely writes outside its bounds due to struct
padding.
struct data_packet{
unsigned char seqnumber;
// There maybe padding here.
char data[500];
// There maybe padding here.
}
struct data_packet packettosend;
char buffer[501]; // May be too small for `packettosend`
memcpy(buffer, &packettosend, sizeof(packetosend));
Alternative: Make buffer[]
certainly big enough
// char buffer[501];
char buffer[sizeof packetosend];
To send just the data and not certainly not any padding:
Pack the data with an implementation specific keyword (if available)
// struct data_packet{
packed struct data_packet{
Or perform 2 sends
int s1 = sendto(socketfd, &buffer.seqnumber, sizeof buffer.seqnumber, ...);
int s2 = sendto(socketfd, buffer.data, sizeof buffer.data, ...);
Or copy carefully
#define SEQ_DATA (sizeof buffer.seqnumber + sizeof buffer.data)
char buffer[SEQ_DATA];
memcpy(buffer, &buffer.seqnumber, sizeof buffer.seqnumber);
memcpy(buffer + sizeof buffer.seqnumber, buffer.data, sizeof buffer.data);
int s = sendto(socketfd, buffer, sizeof buffer, ...);
Adjust recvbuffer[]
size to match.
Upvotes: 1
Reputation: 89
My first suggestion is to zero out your buffer before filling it in and sending it out, just to avoid garbage values. And you need to define a protocol - you can only send and receive raw bytes over the network. Make it so that the receiving end interprets the first byte as the sequence number, and the rest as the actual message itself. This can be done by simply casting the recvbuffer into a struct data_packet
, as the underlying byte layout is the same.
Upvotes: 1