-
-
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); | |
} | |
} |
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)."
Sem fazer as modificações, compila :P. Agora, sabe o porque? Será que tem alguma lib que é incluída por default (arp.*, por exemplo)?