Структура отправки с использованием recvfrom() и sendto()
-
22-07-2019 - |
Вопрос
Я использую Язык 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);
Итак, по сути, я хочу отправить структуру с сервера клиенту.Но из приведенных выше фрагментов кода я получаю ошибки сегментации, и я не уверен, осуществима ли такая передача структуры.Есть ли какой-нибудь выход?
Решение
Во-первых, вы должны выполнить malloc (), чтобы выделить память для структуры hostent. Вы можете передать структуру с помощью sendto () / recvfrom (), но поскольку структура hostent содержит указатели, члены этой структуры, которые являются указателями, не имеют смысла, как только они передаются на другой конец.
Другие советы
Я бы удалил & amp; перед лс
Как правило, вы хотите избежать передачи необработанных структур по сетям, если только они специально не были разработаны для использования в качестве сетевого транспорта, или если вы не абсолютно уверены, что оба конца всегда будут иметь точно такую же архитектуру.Различия в заполнении и порядке следования байтов могут привести к искажению данных на другом конце.Конкретный тип структуры, который вы пытаетесь передать, просто не будет работать при отправке в необработанном виде (см. Ответ Petros).
Проблема в вашем коде отправки заключается в том, что hp является указателем, и вы обрабатываете его так, как будто это данные, на которые он указывает.sizeof(hp) возвращает размер указателя, а не размер структуры, на которую указывает hostent.Кроме того, вы создаете указатель на указатель во втором аргументе 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);
Если hp является указателем, почему вы берете его адрес?
Вы должны исправить код, как показано ниже:
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);
Всегда полезно читать документацию по функциям сокетов.
Кстати, если я рассмотрю очень общий вопрос в вашем посте, т. е. "я хочу отправить структуру с сервера клиенту", я бы порекомендовал взглянуть на следующий пост в SO: