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