Reputation: 103
I'm writing a small client server application in C.
At the client side i have one structure like,
#pragma pack(1) // this helps to avoid serialization while sending over network.
typedef struct _viewBoxClient_Info
{
unsigned long viewBoxID;
int bRT_flag;
int nFrameNum;
char frameData[1000];
}viewBoxClient_info_send ;
#pragma pack(0) // turn packing off
and filling the variable as,
struct _viewBoxClient_Info client_info;
client_info.bRT_flag= 10;/*0 for false, 1 for true*/
client_info.viewBoxID=10000;
memcpy(client_info.frameData,buf,sizeof(client_info.frameData)); //char buf[] data is "is 1st line"
client_info.nFrameNum=1;
and sending to server by using the following function,
send(sock, (char *)&client_info, bytesRead, 0);
At the server side,i have one structure like (same as client side structure),
#pragma pack(1) // this helps to avoid serialization while sending over network.
typedef struct _lclviewBoxClient_Info
{
unsigned long viewBoxID;
int bRT_flag;
int nFrameNum;
char frameData[1000];
}viewBoxClient_info_receive ;
#pragma pack(0) // turn packing off
and receiving the message and printing on screen as,
viewBoxClient_info_receive lcl_viewBox;
ssize_t bytesReceived = recv( *nfd, &lcl_viewBox, sizeof(struct _lclviewBoxClient_Info), 0);
printf("\nlcl_viewBox.bRT_flag:%d\n",lcl_viewBox.bRT_flag);
printf("lcl_viewBox.nFrameNum:%d\n",lcl_viewBox.nFrameNum);
printf("lcl_viewBox.frameData:%s\n",lcl_viewBox.frameData);
O/p at server screen,
lcl_viewBox.bRT_flag:1
lcl_viewBox.nFrameNum:1936287860
lcl_viewBox.frameData: is 1st line
I do not know what exactly its happening at my server side. I'm sending 10 for bRT_flag from client and receiving 1 at server. Also sending nFrameNum=1 from client and receiving as nFrameNum:1936287860 at server. frameData also at client side i'm sending "This is 1st line" and at server receiving only "is 1st line". Will someone help in to get rid of this problem?
thanks and regards,
Sri
Upvotes: 3
Views: 6363
Reputation: 17406
One explanation would be that your client and server have different interpretation for the size of "unsigned long". (Running on different machines or different compiler options, other being 32-bit and other 64-bit).
That would explain the symptoms:
Trivial check for this would be to check sizeof(the struct) or sizeof(unsigned long) to see if they match.
Please see Mike Weller's post for how to fix this properly.
Upvotes: 0
Reputation: 45598
Sending raw structures like this is a very bad idea.
You have to deal with endianness (byte order), packing (which can still be a problem even with #pragma pack
) and another problem you have is that the sizes of types like 'int' can vary between platforms.
I would recommend a serialization library like Google Protocol Buffers to help you with this. If you still want to do it yourself, you need to look up functions like htonl
to convert integer types to network byte-order, and start using fixed-size primitives like uint32_t
etc.
You should also stop sending the entire struct at once and instead write helper functions like writeClientStruct(int sock, struct client_struct *) which will send each member value separately to avoid packing problems between platforms.
Upvotes: 2
Reputation:
Shouldn't this:
send(sock, (char *)&client_info, bytesRead, 0);
be:
send(sock, (char *)&client_info, sizeof( client_info ), 0);
And you should check the return value of send() and particularly of recv() - there is no guarantee that a call to recv will fetch your structure in one go.
Upvotes: 2