#include #include #include #include #include #include extern int errno; #define QLEN 1 // Fila de requisicoes de conexoes pendentes #define IPMAXSTRSIZE 16 //########################################################## // main //########################################################## #define STRINGSIZE 90 #define BUFFERSIZE 512 int perdaconexao = 0; void trataSIGpipe() { printf("SIGPIPE -Perda de conexao \n"); perdaconexao = 1; } void trataSIGio() { printf("SIGIO - Perda de conexao \n"); perdaconexao = 1; } void trataSIGint() { printf("Interrupcao \n"); } int main() { int sd; // socket descriptor int newsd; // novo socket descriptor int status; // estado int size; // tamanho char * IPstring; char string[STRINGSIZE]; // buffer temporario para string char buffer[BUFFERSIZE]; // buffer temporario para dados int serverport; // porta (formato host) struct sockaddr_in serversocketaddr; // end. socket (IP+porta) do servidor struct sockaddr_in clientaddr; // end. socket (IP+porta) do cliente struct hostent * hostentryp; // host entry (p/ traducao nome<->ip) struct servent * serventryp; // host entry (p/ traducao nome<->ip) serversocketaddr.sin_family = AF_INET; //address family internet serversocketaddr.sin_addr.s_addr = INADDR_ANY; //todos ends. IPs do servidor //#################### // servico/porta //#################### // Requisita nome do servico printf("SERVICENAME: "); scanf("%s",buffer); // Verifica se string informada representa um inteiro serverport = atoi(buffer); if (serverport > 65535) { printf("Valor de porta invalido. \n"); exit(1); } else if (serverport > 0) serversocketaddr.sin_port = htons((unsigned short int) serverport); else if (serverport <= 0) { // String informada nao e' um inteiro serventryp = getservbyname(buffer,"tcp"); if (serventryp != NULL) { serversocketaddr.sin_port = serventryp->s_port; } else { printf("Nome do servico (ou porta) invalido. \n"); exit(1); } } //#################### // imprime IP e porta //#################### IPstring = inet_ntop(AF_INET,&serversocketaddr.sin_addr,string,STRINGSIZE); if (IPstring == NULL) perror("Erro na conversao do endereco IP"); printf("Endereco IP do servidor = %s \n",string); printf("Porta do servidor = %hu \n",ntohs(serversocketaddr.sin_port)); /****************************************************************/ /* Socket(): Criacao do socket */ /****************************************************************/ sd = socket(PF_INET,SOCK_STREAM,6); // 6="tcp" if (sd < 0) { printf("Erro na criação do socket. \n"); perror("Descricao do erro"); exit(1); } /****************************************************************/ /* Bind(): associa o socket a um IP e a uma porta */ /****************************************************************/ status=bind(sd,(struct sockaddr *)&serversocketaddr,sizeof(struct sockaddr_in)); if (status < 0) { perror("Erro na chamada bind()"); exit(1); } //trata interrupção do usuário (control-C) //signal(SIGINT,trataSIGint); /********************************************************************/ /* listen(): Ativa o socket no modo passivo para aceite de conexoes */ /********************************************************************/ status = listen(sd,QLEN); if (status != 0) { perror("Erro na chamada listen()"); exit(1); } /****************************************************************/ /* accept(): aceita uma conexao da fila de conexoes pendentes */ /****************************************************************/ while (1) { size = sizeof(clientaddr); newsd = accept(sd,(struct sockaddr *) &clientaddr,(socklen_t *) &size); if (newsd < 0) { perror("Erro na chamada accept()"); exit(1); } signal(SIGPIPE,trataSIGpipe); signal(SIGIO,trataSIGio); IPstring = inet_ntop(AF_INET,&clientaddr.sin_addr,string,STRINGSIZE); if (IPstring == NULL) perror("Erro na conversao do endereco IP"); printf("Endereço do cliente: %s\n",string); printf("Porta do cliente = %hu \n",ntohs(clientaddr.sin_port)); /****************************************************************/ /* read() & write(): */ /****************************************************************/ while (1) { status=read(newsd,buffer,BUFFERSIZE); if (status == 0) { printf("ZERO bytes recebido \n"); break; } else if (status < 0) { perror("ERRO no recebimento de segmento TCP \n"); break; } else { if (perdaconexao) break; buffer[status]='\0'; //Na duvida, insere delimitador para imprimir no terminal printf("RECEBIDO: %s \n",buffer); status = write(newsd,buffer,strlen(buffer)+1); if (status < 0) { printf("ERRO no envio de segmento TCP \n"); break; } } } printf("Encerrando conexão ... \n"); close(newsd); } close(sd); }