Pular para o conteúdo

Envio de dados via socket [RESOLVIDO]

Responder tópico
  • Denunciar
  • Indicar

1. Envio de dados via socket [RESOLVIDO]

Enviado em 04/05/2009 - 00:58h

Galera, estou com um problema da seguinte ordem. Preciso enviar dados de um cliente para um servidor via socket. Tipo envio uma matriz nxn e um comando, ordenar, determinante, diagonal principal etc. Só que não consigo enviar dados diferentes de strings como doubles, int entre outros. Só para exemplo eu tentei o seguinte: a aplicação cliente envia dois numeros para o servidor e este calcula a soma dos dois numeros e envia o total para o cliente. Mas não dá certo. Como façço para enviar dados do tipo int via socket? Segue o codigo cliente:

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>

int main(int argc, char *argv[]) {

struct sockaddr_in server_addr;
int iSock, num1, num2;
char op[100];

/*if (argc != 2) {
fprintf(stderr, "USAGE: clientsocket <word>\n");
exit(1);
}*/

iSock = (socket(AF_INET, SOCK_STREAM, 0));
if(iSock < 0){
perror("Erro ao criar socket ");
exit(1);
}

//memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5010);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
bzero(&(server_addr.sin_zero), 8);

if(connect(iSock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0){
perror("Erro ao conectar \n");
exit(1);
}

int iBytes, buffer__;
char buffer_[200];

printf("Digite o primeiro número: ");
scanf("%d", &num1);
//puts("Digite o segundo número: ");
//scanf("%d", &num2);
/*puts("Digite o operador: ");
scanf("%s", &op);*/

puts("====================== Resultado ==========================");

itoa(num1,buffer_,10);
//Enviando dados.
if(send(iSock, buffer_, strlen(num1), 0) < 0){
perror("Erro ao enviar a mensagem \n");
exit(1);
}

// if(send(iSock, num2, strlen(num2), 0) < 0){
// perror("Erro ao enviar a mensagem \n");
// exit(1);
// }

/*if(send(iSock, op, strlen(op), 0) < 0){
perror("Erro ao enviar a mensagem \n");
exit(1);
}*/

//Enviando dados.
//if(send(iSock, buffer_, strlen(buffer_), 0) < 0){
// perror("Erro ao enviar a mensagem \n");
// exit(1);
//}

//Recebendo dados.
if ((iBytes = recv(iSock, buffer__, strlen(buffer__), 0)) < 0){
perror("Erro ao receber mensagem \n");
exit(1);
}

//buffer__[iBytes] = '{TEXTO}';

printf("\nResposta: %d\n", buffer__);

close(iSock);

return EXIT_SUCCESS;
}

código servidor:

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>

int main(void) {

int iSock;
struct sockaddr_in server_addr;

iSock = socket(AF_INET, SOCK_STREAM, 0);
if (iSock < 0){
printf("Erro ao criar socket \n");
exit(1);
}

memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5010);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
//bzero(&(server_addr.sin_zero), 8);

if (bind(iSock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0){
printf("Erro ao executar bind \n");
exit(1);
}

if (listen(iSock, 1) < 0){
printf("Erro ao escutar na porta 5010 \n");
exit(1);
}

while (1){

int iFd, total, op, num1 = 10, num2;
struct sockaddr_in client_addr;
socklen_t sin_size;
char szMessage[200];

sin_size = sizeof(struct sockaddr_in);

if ((iFd = accept(iSock, (struct sockaddr *) &client_addr, &sin_size)) < 0) {
perror("Erro ao estabelecer conexão com o cliente \n");
exit(1);
}

printf("Cliente conectado: %s\n", inet_ntoa(client_addr.sin_addr));

/*if (send (iFd, inet_ntoa(client_addr.sin_addr), strlen(inet_ntoa(client_addr.sin_addr)), 0) < 0){
perror("Endereço do cliente desconhecido ");
exit(1);
}*/

int Bytes_rec, Bytes_rec2, Bytes_rec3;

if ((Bytes_rec = recv(iFd, atoi(num1), strlen(num1), 0)) < 0){
printf("Erro ao receber mensagem do cliente \n");
exit(1);
}

//if ((Bytes_rec2 = recv(iFd, num2, strlen(num2), 0)) < 0){
// printf("Erro ao receber mensagem do cliente \n");
// exit(1);
//}

/*if ((Bytes_rec3 = recv(iFd, op, strlen(op), 0)) < 0){
printf("Erro ao receber mensagem do cliente \n");
exit(1);
}*/

//bloco original
//if ((Bytes_rec = recv(iFd, szMessage, 200, 0)) < 0){
// printf("Erro ao receber mensagem do cliente \n");
// exit(1);
//}

szMessage[Bytes_rec] = '{TEXTO}';
//num1[Bytes_rec] = '{TEXTO}';
//num2[Bytes_rec2] = '{TEXTO}';
//num3[Bytes_rec3] = '{TEXTO}';

//num1[Bytes_rec] = '{TEXTO}';
//num2[Bytes_rec] = '{TEXTO}';
//op[Bytes_rec] = '{TEXTO}';

total = num1 + num2;

/*switch(op){
//soma
case 1: {
total = num1 + num2;
break;
}
case 2: {
//subtração
total = num1 - num2;
break;
}
case 3: {
//multiplicação
total = num1 * num2;
break;
}
case 4: {
//divisão
total = num1 / num2;
break;
}
default:
printf("Error: Invalid option!");
break;
}*/


//mess_rec[Bytes_r] = '{TEXTO}';

//memset(szMessage, 0, sizeof(szMessage));
//szMessage[0] = "Recebi Judson\n";
//strcpy(szMessage, "Devolvendo o DIA\n");

//bloco original
//if (send(iFd, szMessage, 200, 0) < 0){
// printf("Erro ao enviar mensagem para o cliente \n");
// exit(1);
//}

if (send(iFd, atoi(num1), strlen(num1), 0) < 0){
printf("Erro ao enviar mensagem para o cliente \n");
exit(1);
}

close(iFd);
}
return EXIT_SUCCESS;
}

Responder tópico

2. ae

Melhor resposta

Enviado em 07/05/2009 - 08:19h

agora que to com mais tempo (mas ainda não deu pra testar)... só pra te explicar melhor...
o socket é um tipo de stream... ou seja... uma sequencia de bytes enviados de um lado e lido do outro e vice-versa... como quase tudo no mundo da informática...
o send ou recv basicamente recebem um ponteiro como parâmetro que é um endereço de memória onde estão os dados, e uma quantidade de bytes que vai ler dali pra frente... ou seja... passando quanquer endereço e uma quantidade de bytes... ele le e envia ou recebe em um outro ponteiro... (por isso o parâmetro dele é void *)

A quantidade vai depender do tipo... uma string (ou char *) já é um ponteiro, e por isso que na hora de mandar usa-se strlen(variavel) para pegar o total de bytes até o caracter nulo!

Qualquer outro tipo primitivo que não seja ponteiro (por ex. a int ou double), é preciso passar para ele o endereço da memória (por isso usar o &), e então a quantidade de bytes ou melhor... tamanho do tipo...

Procure no google sobre Intel Integer e de uma lida... para ver teoricamente o que é um inteiro!

Volto a falar... não testei o código (já que geralmente uso socket para alguns protocolos web que trabalham com string)... mas basicamente em C é assim!

Boa sorte!

3. Envio de dados via socket

Enviado em 06/05/2009 - 17:14h

Karvox, o prof. Valentim falou que era melhor usar string... que ficaria mais fácil.

4. amigo

Enviado em 06/05/2009 - 19:02h

Eu nunca precisei mandar int, mas teoricamente não há problemas... to sem tempo agora para testar, mas tente:

if(send(iSock, &num2, sizeof(int), 0) < 0){

ou se prefererir ao invésd e sizeof(int) coloque 4, afinal um int tem o tamanho de 4 bytes ou 32 bits

5. Re: Envio de dados via socket [RESOLVIDO]

Enviado em 08/05/2009 - 22:09h

A resposta do stremer está perfeita e assino embaixo.

para não ficar sem contribuir em nada, ainda tem outra solução: converte para string!

No cliente (quem envia)

char buf[1000];

sprintf(but,"%d %d", num1, num2);
send(iFd, buf, strlen(buf),0);

No servidor:
Bytes_rec = recv(iFd, buf, 1000, 0);

sscanf(buf, "%d "%d", &num1, &num2);

mas isto só porque o stremer saiu na frente e queimou a solução que eu daria... ;-)

6. Re: Envio de dados via socket [RESOLVIDO]

Enviado em 08/05/2009 - 22:22h

permitam-me também contribuir com meus 2 centavos :D

não esquecer da ordem dos bytes, pois nunca se sabe se do outro lado teremos little ou big endian. então, sempre converta o int com htonl antes de enviar, e 'desconverta' com ntohl após receber.

7. Re: Envio de dados via socket [RESOLVIDO]

Enviado em 08/05/2009 - 22:24h

Caracas, tem razão!!

Isto pode derrubar a versão de enviar os bytes crus do int!
Sem falar que pode ter máquinas onde o tamanho do int não é 4 bytes!!

BOA!

8. Re: Envio de dados via socket [RESOLVIDO]

Enviado em 08/05/2009 - 22:31h

verdade. para contornar a questão do tamanho do int e manter a portabilidade, pode-se usar um tipo int32_t, int64_t, etc, a gosto do freguês.

9. ae

Enviado em 13/05/2009 - 18:14h

não entrei nos detalhes dos tipos de int... pois a pergunta era mais focada em tipos primitivos...
mas legal vocês terem citado... inclusive isso vale para muitas outras coisas (não somente socket)...

10. RESOLVIDO

Enviado em 23/05/2009 - 20:26h

Bom galera, quero agradeçer a toda a rapaziada que me ajudou e especialmente ao STREMER que com a dica dele consegui resolver o problema. Então ficou assim:

Aqui o servidor recebendo os dados

...

if ((iBytes = recv(iSock, &impar, sizeof(int), 0)) < 0){
perror("Erro ao receber mensagem \n");
exit(1);
}

//*buff_impar[iBytes] = '\0';
...


Aqui enviando os dados

...
int impares;

if (send(iFd, &impares, sizeof(int), 0) < 0){
printf("Erro ao enviar mensagem para o cliente \n");
exit(1);
}
...


Simplesmente com isso resolveu a questão de enviar e receber inteiros ou array de inteiros via socket. No meu caso eu recebi uma matriz de char e converti em uma matriz de inteiros, fiz algumas operações que necessitei e enviei as veráveis resultantes como vocês veem acima. Galera muito obrigado a todos vocês pela ajuda. Qualquer coisa estamos aí!

11. Re: Envio de dados via socket [RESOLVIDO]

Enviado em 23/05/2009 - 20:38h

: )

Responder tópico

Responder tópico

Entre na sua conta para responder.

Fazer login para responder