Confuso com a função send() (Programação socket)

1. Confuso com a função send() (Programação socket)

Junior
2016henrique

(usa Ubuntu)

Enviado em 25/04/2016 - 18:39h

ssize_t send(int socket, const void * buffer, size_t len, int flags);

Fiz um programa q delcarava uma char str[3] e copiava a string p a função send. até aí tudo normal. Mas inventei de declarar uma variavel inteira e retornou erro. Agora me pergunto: se const void * buffer aceita variaveis char, entao pq não aceita variaveis int?


  


2. Re: Confuso com a função send() (Programação socket)

Paulo
paulo1205

(usa Ubuntu)

Enviado em 25/04/2016 - 19:12h

2016henrique escreveu:

ssize_t send(int socket, const void * buffer, size_t len, int flags);

Fiz um programa q delcarava uma char str[3] e copiava a string p a função send. até aí tudo normal. Mas inventei de declarar uma variavel inteira e retornou erro. Agora me pergunto: se const void * buffer aceita variaveis char, entao pq não aceita variaveis int?


Porque a str que você declarou não é do tipo char, mas sim do tipo array de caracteres, que decai automaticamente para ponteiro para caracteres quando usada numa expressão que não envolva os operadores sizeof ou & sobre o array.

O segundo argumento de send() requer um endereço (ponteiro) para objeto de qualquer tipo (esse é o sentido de “void *”), mas tem de ser ponteiro. Quando você colocou o nome do array como argumento, o decaimento para ponteiro o tornou um argumento aceitável.

Se você quiser transmitir um inteiro, terá de guardar o valor desejado numa variável, e então passar o endereço dessa variável para a função send(), bem como o tamanho ocupado na memória pela variável. Mais ou menos do seguinte modo.

// Código que transmite o valor 123456789 via socket.
int i=123456789;
send(sock, &i, sizeof i, 0);


&i” devolve o endereço (ponteiro) da região de memória que armazena o valor de i, e “sizeof i” informa quantos bytes consecutivos da memória esse valor ocupa (tipicamente quatro bytes, nos nossos PCs).

Note que a transmissão do valor é feita de forma binária. Para que o recebedor do dado transmitido entenda que aquele conjunto de bytes corresponde ao valor 123456789, ele terá de ter a mesma representação interna do dado que o remetente tiver. Nossos PCs com processadores Intel ou AMD usam uma representação que coloca os bytes menos significativos do número primeiro (chamada de “little endian”), mas existem muitas arquiteturas que usam a representação oposta, com bytes mais significativos primeiro (chamada “big endian”). A própria Internet, aliás, usa representação big endian por padrão em todos os seus protocolos, e a chama convencionalmente de “network byte order”.

Assim sendo, não se surpreenda se você vir que, ao transmitir um inteiro em modo binário do seu computador para o seu celular, o número mostrado pelo celular aparecer trocado (por exemplo, você envia 123456789, que no PC corresponde à sequência de bytes 0x15, 0xCD, 0x5b, 0x07, e o celular mostra 365779719), pois isso pode acontecer se o seu celular for big endian. Uma das melhores formas de evitar incompatibilidades desse tipo é usar texto para transferir dados (tanto texto puro quanto XML, JSON ou YAML, dependendo da necessidade). Outra forma é combinar uma representação comum (por exemplo: todos os nós colocam seus dados binários simples em network byte order, e procuram decompor dados mais complexos em pedaços menores, que serão recompostos pelo destinatário).






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts