Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Carycccs

Enviando union/struct via TCP IP

Recommended Posts

Olá! Boa tarde a todos!

 

Estou desenvolvendo um programa Cliente/Servidor que deve enviar 7 valores booleanos do Servidor para o Cliente.

Esses dados estão alocados em uma struct:

 

*** No Servidor ***

 

struct movimentos{
bool Frente;
bool Esquerda;
bool Direita;
bool Parado;
bool PassoDireita;
bool PassoEsquerda;
}m;
E utilizo uma união que inclui esses dados e identifica o tamanho da estrutura:
union dados{
movimentos m;
char tamanho [(sizeof movimentos)];
}uniao;

E depois eu uso a função send enviando o endereço da estrutura para o cliente, assim como o seu tamanho:

 

send(winsock, uniao.tamanho, sizeof(uniao.tamanho), 0); (Está certo ou eu deveria fazer de outro modo?)
*** No Cliente ***
Eu tenho a mesma estrutura que deve receber os valores presentes no endereço da estrutura assada pela função send no servidor:
struct movimentos{
bool Frente;
bool Esquerda;
bool Direita;
bool Parado;
bool PassoDireita;
bool PassoEsquerda;
}m;
Que também possui uma união: (Ou aqui ela não precise existir?)
union dados{
movimentos m;
char tamanho [(sizeof movimentos)];
}uniao;
E recebo (ou acho que recebo né, posso estar fazendo errado) esses dados com a função recv:
recv(winsock,uniao.tamanho,sizeof(uniao.tamanho),0);
O que eu não consigo fazer é receber os dados booleanos enviados pelo Servidor e utilizá-los no Cliente.
Gostaria de saber se estou fazendo tudo errado ou esse é o caminho?
Fui instruída a passar os dados dessa forma, com um struct que possui os dados e uma union que engloba a struct e seu tamanho.
Mas fico em dúvida sobre o que passar no segundo argumento da função send, ou o que eu estou passando está correto?
Socorro!
=)
Obrigada!
confused.gif confused.gif confused.gif confused.gif confused.gif confused.gif confused.gif

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fica um pouco complicado dizer se está errado ou não olhando apenas poucas parte do código.

 

O que se deve ter em mente ao trabalhar com sockets (ou qualquer outro meio de comunicação, como serial por exemplo) é que, são transmitidos bytes. Ou seja, precisa pegar a região de memória onde está a tua união e transmitir pelo canal de comunicação. Do outro lado deve armazenar em um tipo de dado que seja igual ao que foi enviado, que você já faz (A função recv faz isso).

 

Se você esta armazenando no vetor char tamanho [(sizeof movimentos)]; todos os dados da união em algum lugar do código, então está correto.

 

Uma forma de averiguar isso, é depurar as duas aplicações. E ver extamente o que está enviando no momento da chama send e o que está recebendo na função recv. Outra forma é monitorar a comunicação com um analisador de protocolo, como o Wireshark.

 

Espero ter explicado claramente...

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • GBecker, o meu problema é que eu não sei fazer exatamente o que você acha que eu estou fazendo, que é armazenar no char tamanho [(sizeof movimentos)], os dados que eu preciso enviar para o cliente. E no cliente, como eu recebo um char, eu não sei atribuir ao struct que eu tenho, os dados do struct enviados pelo servidor. No cliente eu não sei imprimir o que estou recebendo....

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, vou tentar explicar

int send(int Meusocket, const void *msg, size_t len, int flags);

Esta é a função que envia dados através do socket. Os parâmetros dela:

 

Meusocket -> É socket(canal de comunicação) que você abriu.

*msg -> São os dados/bytes que serão enviados pelo socket.

len -> É a quantidade de bytes que serão enviados.

flags -> Configurações adicionais do canal de comunicação.

 

Como é preciso enviar a estrutura, deve primeiro colocá-la em um vetor de char. Desta forma:

pucDados = malloc( elementos * sizeof(dados) );
memcpy(pucDados,dados,sizeof(dados));

Na primeira linha, é feito alocação dinâmica de um vetor de char para comportar os dados que serão enviados. Na expressão elementos * sizeof(dados), elementos é quantidade de dados do tipo da estrutura e o sizeof recupera o tamanho em bytes ocupado pela estrutura. Digamos que você tenha um vetor do tipo da estrutura dados, com três elementos e, hipoteticamente, a estrutura ocupe 10 bytes em memória. Logo, essa expressão vai retorna que 3 * 10 = 30 bytes ou 30 posições no vetor de char.

Na segunda linha utilizo o memcpy para copiar a região de memória ocupada pela estrutura para o vetor recém alocado.

OBS.: Utilizo um vetor de char pis o char é o menor tipo de dado do C, 1 byte.

 

De posse deste vetor pode chamar a função send.

send(Meusocket, pucDados,(elementos * sizeof(dados)),0)

Atente que o tamanho passado na função é obtido pela mesma expressão utilizada na alocação dinâmica feita anteriormente.

 

 

======================================================================================================

 

Na recepção:

 

 

int recv(int Meusocket, void *buf, int len, unsigned int flags);

Meusocket -> Socket local aberto para recepção.

buf -> É o buffer onde serão armazenados os dados recebidos

len -> Tamanho do buffer.

flags -> Configurações adicionais do canal de comunicação.

 

Para extrair os dados do buffer a lógica deve ser a seguinte. Imagine esse buffer como um vetor que armazena dados do tipo estrutura dados.

Copie a primeira posição do "vetor" para uma variável separada (no caso, do tipo estrutura dados) e mova o restante para a esquerda.

Repita o processo até retirar todos os dados. Para obter a quantidade de elementos que foi recebida, pode utilizar o tamanho do buffer também recebido (len) dividindo pelo tamanho da estrutura em bytes (sizeof(dados)).

O algorítmo é o mesmo utilizado para retirar dados de uma estrutura de dados do tipo fila. Para retirar os dados utilize as funções memcpy ou memmove.

 

============================================================================================================

 

Minha explicação deve ter ficado confusa. =P

Essa é apenas uma ideia de algorítmo, pode apresentar problemas que devem ser trabalhos na implementação.

 

Para testar esta segunda parte, crie um código com um vetor que armezene estruturas. E faça operações com memmove e memcpy, depurando para visualizar os dados.

 

Em caso de dúvida coloco esse dois links no post:

http://www-usr.inf.ufsm.br/~giovani/sockets/sockets.txt

http://www.vivaolinux.com.br/artigo/Alocacao-dinamica-de-memoria-em-C

 

O primeiro, é um link da UFSM. Com explicações sobre programação em sockets, um ótimo material.

O segundo link é um artigo do viva o linux!, sobre alocação dinâmica.

 

Caso não conheça o algorítmo de fila:

http://www.ime.usp.br/~pf/algoritmos/aulas/fila.html

Recomedo que estude sobre alocação dinâmica de memória.

 

Espero ter ajudado, FLW!

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.