views:

811

answers:

5

I am using C language which is a common platform for both the server and the client.

I have a structure of a particular type which I want to send to the client from the server.

For e.g.

SERVER CODE

 //necessary declarations

struct hostent *hp;

hp=gethostbyname("www.google.com");

sendto(sockDes,&hp,sizeof(hp),0,(struct sockaddr *)&cli_addr,sizeof(cli_addr));

CLIENT CODE

struct hostent *hp;

msg=recvfrom(mysock,&hp,sizeof(hp),0,(struct sockaddr)&serv_addr,&size_len);

So , basically I want to send a structure from the server to the client.But from the above pieces of code I am getting segmentation faults , and I am not sure whther such structure transfer is feasible, IS THERE ANY WAY OUT?

+4  A: 

I'd remove the & in front of hp

Eric
A: 

If hp is a pointer, why are you taking its address?

Amber
+4  A: 

In general you want to avoid transferring raw structures over networks unless they have specifically been designed for use as network transport, or unless you are absolutely sure that both ends will always be exactly the same architecture. Differences in padding and byte ordering may cause the data to appear garbled at the other end. The particular type of struct you are trying to transfer just will not work being sent raw (See the answer by Petros)

The problem in your send code is that hp is a pointer and you are treating it like it is the data it points to. sizeof(hp) returns the size of a pointer, not the size of the pointed-to hostent struct. Also, you are creating a pointer-to-pointer in the second argument of sendto when you do not mean to. The sending code should read:

struct hostent *hp;

hp=gethostbyname("www.google.com");

sendto(sockDes,hp,sizeof(*hp),0,(struct sockaddr *)&cli_addr,sizeof(cli_addr));

You also have a problem in the receive code. You are supposed to allocate space for recvfrom to store the data it received. It does not allocate it for you. Change your receive code to one of these two:

// Store on the stack
struct hostent h;

msg=recvfrom(mysock,&h,sizeof(h),0,(struct sockaddr)&serv_addr,&size_len);

or

// Store on the heap, be sure to free() when done
struct hostent * hp = malloc(sizeof(struct hostent));

msg=recvfrom(mysock,hp,sizeof(*hp),0,(struct sockaddr)&serv_addr,&size_len);
Tyler McHenry
+1  A: 

You should correct the code as shown below:

struct hostent *p_hp = gethostbyname("www.google.com");
struct sockaddr_in cli_addr;
sendto(sockDes,p_hp,sizeof(hostent),0,(SOCKADDR *)&cli_addr,sizeof(cli_addr));


struct hostent hp;
struct sockaddr_in serv_addr;
int size_serv_addr = sizeof(serv_addr);
msg=recvfrom(mysock,&hp,sizeof(hostent),0,(SOCKADDR *)&serv_addr,&size_serv_addr);

It would always help to read the documentation on socket functions.

Indeera
+3  A: 

First, you have to malloc() in order to allocate memory for the struct hostent. You can transfer a struct through sendto()/recvfrom() but since struct hostent contains pointers, the members of this struct that are pointers have no meaning as soon as they are transfered to other end.

Petros
Good catch! I was looking for segfault causes and not even thinking about what exactly he was trying to transfer.
Tyler McHenry
Ok..then it is insignificant to send the structure hostent.It would be better if I send the contents of the structure string by string to the server.
Biswajyoti Das
That's correct, and that's usually the case. You really don't want to be transmitting anything other than characters or integers over a network unless you are very careful about it. And when you transmit integers, be sure to convert them to/from network byte order using the htonl/htons/ntohl/ntohs family of functions.
Tyler McHenry