Отправка структуры с использованием recvfrom () и sendto () - PullRequest
3 голосов
/ 04 августа 2009

Я использую язык C , который является общей платформой для сервера и клиента.

У меня есть структура определенного типа, которую я хочу отправить клиенту с сервера.

Например,

КОД СЕРВЕРА

 //necessary declarations

struct hostent *hp;

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

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

КОД КЛИЕНТА

struct hostent *hp;

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

Итак, в основном я хочу отправить структуру с сервера клиенту. Но из приведенных выше фрагментов кода я получаю ошибки сегментации, и я не уверен, возможна ли такая передача структуры. Есть ли выход?

Ответы [ 6 ]

6 голосов
/ 04 августа 2009

Во-первых, вы должны выполнить malloc (), чтобы выделить память для структуры hostent. Вы можете передать структуру с помощью sendto () / recvfrom (), но поскольку структура hostent содержит указатели, члены этой структуры, которые являются указателями, не имеют смысла, как только они передаются на другой конец.

4 голосов
/ 04 августа 2009

Как правило, вы хотите избежать передачи необработанных структур по сетям, если они специально не предназначены для использования в качестве сетевого транспорта или если вы не абсолютно уверены, что оба конца всегда будут иметь одинаковую архитектуру. Различия в заполнении и порядке байтов могут привести к искажению данных на другом конце. Конкретный тип структуры, которую вы пытаетесь перенести, просто не будет работать в исходном виде (см. Ответ Петроса)

Проблема в вашем коде отправки состоит в том, что hp является указателем, и вы рассматриваете его так, как будто это данные, на которые он указывает. sizeof (hp) возвращает размер указателя, а не размер структуры, на которую указывает указатель. Кроме того, вы создаете указатель на указатель во втором аргументе sendto, когда не хотите этого делать. Код отправления должен гласить:

struct hostent *hp;

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

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

У вас также есть проблема в коде получения. Вы должны выделить место для recvfrom для хранения полученных данных. Он не выделяет его для вас. Измените свой код получения на один из этих двух:

// Store on the stack
struct hostent h;

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

или

// 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);
4 голосов
/ 04 августа 2009

Я бы удалил & перед hp

1 голос
/ 04 августа 2009

Вы должны исправить код, как показано ниже:

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

Это всегда поможет прочитать документацию по функциям сокета.

1 голос
/ 04 августа 2009

Если hp является указателем, почему вы берете его адрес?

0 голосов
/ 29 октября 2013

Кстати, если я рассмотрю очень общий вопрос в вашем посте, т. Е. «Я хочу отправить структуру с сервера клиенту», я бы порекомендовал взглянуть на следующий пост в SO:

Передача структуры через сокеты в C

...