-
-
Save marioplumbarius/7863399 to your computer and use it in GitHub Desktop.
| Compile os arquivos: | |
| $ gcc -o executavel_server socket_server.c | |
| $ gcc -o executavel_client socket_client.c | |
| Inicie o server: | |
| $ ./executavel_server | |
| Rode o client: | |
| $ ./executavel_client |
| // se conecta a um server | |
| // e loga mensagens | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <errno.h> | |
| #include <string.h> | |
| #include <sys/socket.h> | |
| #include <netinet/in.h> | |
| #include <time.h> | |
| int main(){ | |
| // endereco | |
| struct sockaddr_in EndLocal; | |
| // descritor, tamanho e retorno do connect | |
| int sockfd, len, retorno; | |
| // armazenara o conteudo retornado | |
| char buffer[1000]; | |
| // abre o socket | |
| sockfd = socket(PF_INET, SOCK_STREAM, 0); | |
| // tamanho do endereco atribuido ao socket | |
| len = sizeof(EndLocal); | |
| // cleanup | |
| memset((struct sockaddr_in *)&(EndLocal), 0, len); | |
| // dominio do socket | |
| EndLocal.sin_family = PF_INET; | |
| // porta | |
| EndLocal.sin_port = htons(4040); | |
| // endereco IP | |
| EndLocal.sin_addr.s_addr = inet_addr("127.0.0.1"); | |
| // tenta se conectar ao server | |
| retorno = connect(sockfd, (struct sockaddr*)&EndLocal, len); | |
| if ( retorno != 0 ) { | |
| perror( "Não foi possível se conectar" ); | |
| exit(1); | |
| } | |
| // recebe a mensagem do server | |
| recv(sockfd, &buffer, sizeof(buffer), 0); | |
| // loga a mensagem recebida | |
| printf("%s\n", buffer); | |
| // fim do programa | |
| exit(0); | |
| } |
| // sobe um server na porta 4040 | |
| // responde uma mensagem estatica | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <sys/socket.h> | |
| #include <netinet/in.h> | |
| #include <time.h> | |
| int main(){ | |
| // enderecos | |
| struct sockaddr_in EndLocal, EndRemoto; | |
| // descritores, retorno e lens | |
| int sockfd_server, len, retorno; | |
| int sockfd_cliente, lenRemoto; | |
| // mensagem | |
| char *buffer; | |
| buffer = malloc(sizeof(char)*100); | |
| // abre um socket | |
| sockfd_server = socket(PF_INET, SOCK_STREAM, 0); | |
| // tamanho do endereco atribuido ao socket do server | |
| len = sizeof(EndLocal); | |
| // cleanup | |
| memset((struct sockaddr_in *)&(EndLocal), 0, len); | |
| // seta a familia/dominio/escopo do socket | |
| EndLocal.sin_family = PF_INET; | |
| // seta a porta que ficara escutando por conexoes | |
| EndLocal.sin_port = htons(4040); | |
| // seta o endereco IP | |
| EndLocal.sin_addr.s_addr = inet_addr("127.0.0.1"); | |
| // atribui o endereco ao socket | |
| retorno = bind(sockfd_server, (struct sockaddr*)&EndLocal, len); | |
| // caso erro, retorna | |
| if ( retorno == -1 ) exit(0); | |
| // escuta por conexoes | |
| // 5 -> tamanho max. fila espera por uma conexao | |
| listen(sockfd_server, 5); | |
| // loga uma mensagem antes de comecar a processar conexoes | |
| printf("%s\n", "Aguardando conexoes na porta:4040" ); | |
| // loop infinito | |
| while(1){ | |
| // bloqueia a execucao do programa, ate que exista um pedido de conexao por parte do cliente | |
| sockfd_cliente = accept( sockfd_server, (struct sockaddr *) &EndRemoto, &lenRemoto ); | |
| // armazena uma string para ser enviada ao cliente | |
| buffer = "Cliente se conectou no servidor!\n"; | |
| // envia para o cliente os dados, seguido do tamanho total de dados sendo enviado | |
| // 0 -> opcional, flags | |
| send(sockfd_cliente, buffer, strlen(buffer), 0); | |
| // fecha a conexao com o cliente | |
| close(sockfd_cliente); | |
| } | |
| } |
Sem fazer as modificações, compila :P. Agora, sabe o porque? Será que tem alguma lib que é incluída por default (arp.*, por exemplo)?
Sobre o socklen_t, eu peguei a assinatura do método de um livro (dai o uso do int) :P, parece que de int, mudou pra size_t (quebrou a compatibilidade) e depois fizeram um socklen_t, que é apenas um "proxy"/compativel para int.
Se liga:
Quoting Linus Torvalds:
"Any sane library must have "socklen_t" be the same size as int.
Anything else breaks any BSD socket layer stuff. POSIX initially did
make it a size_t, and I (and hopefully others, but obviously not too
many) complained to them very loudly indeed. Making it a size_t is
completely broken, exactly because size_t very seldom is the same
size as "int" on 64-bit architectures, for example. And it has to be
the same size as "int" because that's what the BSD socket interface
is. Anyway, the POSIX people eventually got a clue, and created
"socklen_t". They shouldn't have touched it in the first place, but
once they did they felt it had to have a named type for some
unfathomable reason (probably somebody didn't like losing face over
having done the original stupid thing, so they silently just renamed
their blunder)."
A declaração da var lenRemoto não pode ser int, tem que ser:
Segundo a lib socket, method, accept:
http://pubs.opengroup.org/onlinepubs/7990989799/xns/syssocket.h.html