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