Enviando estrutura usando recvfrom () e sendto ()
-
22-07-2019 - |
Pergunta
Eu estou usando linguagem C que é uma plataforma comum para o servidor eo cliente.
Eu tenho uma estrutura de um tipo particular que eu quero enviar para o cliente a partir do servidor.
Por exemplo.
código do servidor
//necessary declarations
struct hostent *hp;
hp=gethostbyname("www.google.com");
sendto(sockDes,&hp,sizeof(hp),0,(struct sockaddr *)&cli_addr,sizeof(cli_addr));
código de cliente
struct hostent *hp;
msg=recvfrom(mysock,&hp,sizeof(hp),0,(struct sockaddr)&serv_addr,&size_len);
Então, basicamente eu quero enviar uma estrutura a partir do servidor para o cliente. Mas a partir dos pedaços de código acima estou recebendo falhas de segmentação, e eu não tenho certeza se essa transferência estrutura é viável. Existe alguma maneira para fora?
Solução
Em primeiro lugar, você tem que malloc () para alocar memória para o hostent struct. Você pode transferir uma struct através sendto () / recvfrom () mas desde struct hostent contém ponteiros, os membros desta estrutura que são ponteiros não têm significado tão logo eles são transferidos para a outra extremidade.
Outras dicas
Eu remover o & na frente de hp
Em geral, você quer evitar a transferência de estruturas matérias sobre redes, a menos que especificamente foram projetados para uso como transporte de rede, ou a menos que você tenha certeza absoluta de que ambas as extremidades será sempre exatamente a mesma arquitetura. Diferenças no estofamento e byte de ordenação pode fazer com que os dados a aparecer com erros na outra extremidade. O tipo particular de estrutura que você está tentando transferir apenas não vai trabalho que está sendo enviada raw (Veja a resposta por Petros)
O problema no seu código de envio é que a HP é um ponteiro e você está tratando as coisas como elas são os dados que ele aponta. sizeof (cv) retorna o tamanho de um ponteiro, não o tamanho do aguçado-a hostent estrutura. Além disso, você está criando um ponteiro-para-ponteiro no segundo argumento de sendto quando não quero. O código de envio deve ler-se:
struct hostent *hp;
hp=gethostbyname("www.google.com");
sendto(sockDes,hp,sizeof(*hp),0,(struct sockaddr *)&cli_addr,sizeof(cli_addr));
Você também tem um problema no código receber. Você é suposto para alocar espaço para recvfrom para armazenar os dados que recebeu. Ele não alocá-lo para você. Mudar a Sua receber o código para um destes dois:
// Store on the stack
struct hostent h;
msg=recvfrom(mysock,&h,sizeof(h),0,(struct sockaddr)&serv_addr,&size_len);
ou
// 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);
Se a HP é um ponteiro, por que você está tomando seu endereço?
Você deve corrigir o código como mostrado abaixo:
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);
Ele sempre ajuda a ler a documentação sobre funções de soquete.
A propósito, se eu considerar a questão muito genérico em seu post, ou seja, "Eu quero enviar uma estrutura a partir do servidor para o cliente", eu recomendo a olhar para o seguinte post sobre SO: