int main(int argc, char * argv[]) { int sockfd, numBytes; struct addrinfo hints, *servinfo, *p; struct sockaddr_storage their_addr; socklen_t sin_size; struct sigaction sa; int yes=1; char s[INET6_ADDRSTRLEN]; int rv; int ativo; char opt[20]; loadMovies(); memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) { perror("server: socket"); continue; } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("server: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "servidor: falha ao realizar 'bind'\n"); return 2; } freeaddrinfo(servinfo); printf("servidor: aguardando recv...\n"); ativo = 1; while(ativo) { if ((numBytes = recvfrom(sockfd, opt, 20 , 0, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("recvfrom"); exit(1); } sin_size = sizeof their_addr; switch(opt[0]){ case '0': ativo = 0; break; case '1': getAllMovieTitles(sockfd, their_addr, sin_size); break; case '2': getMovieByGenre(sockfd, opt, their_addr, sin_size); break; case '3': getMovieSynById(sockfd, opt, their_addr, sin_size); break; case '4': getMovieQtById(sockfd, opt, their_addr, sin_size); break; case '5': getMovieById(sockfd, opt, their_addr, sin_size); break; case '6': getAllMovies(sockfd, their_addr, sin_size); break; case '7': alterQt(sockfd, opt, their_addr, sin_size); break; default: printf("Opcao nao valida. Tente novamente\n"); break; } } close(sockfd); return 0; }
/** * Principal */ int main(int argc, char * argv[]) { //sockfd refere-se à escuta, new_fd a novas conexoes int sockfd, new_fd; struct addrinfo hints, *servinfo, *p; //informacao de endereco dos conectores struct sockaddr_storage their_addr; socklen_t sin_size; struct sigaction sa; int yes=1; char s[INET6_ADDRSTRLEN]; int rv; int ativo; // Booleano que indica se a conexao deve continuar ativa // Vetor que contera a opcao do cliente (mais o id do filme, se for o // caso) char opt[4]; loadBooksFromDB(); memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; // Stream socket hints.ai_flags = AI_PASSIVE; if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // Percorre a lista ligada e realiza 'bind' ao primeiro que for possivel // Cria todos os file descriptors dos sockets, dando nome a eles for(p = servinfo; p != NULL; p = p->ai_next) { //Função SOCKET: cria um socket, dando acesso ao serviço da camada de transporte if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) { perror("server: socket"); continue; } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } //Função bind: atribui um nome ao socket if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("server: bind"); continue; } break; } // Debug de erro if (p == NULL) { fprintf(stderr, "servidor: falha ao realizar 'bind'\n"); return 2; } // Necessario devido à chamada 'getaddrinfo' acima freeaddrinfo(servinfo); // Anuncia que está apto para receber conexões if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } sa.sa_handler = sigchld_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } printf("servidor: aguardando conexoes...\n"); // Loop de aceitacao principal while(1) { sin_size = sizeof their_addr; new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); if (new_fd == -1) { // perror("accept"); continue; } inet_ntop(their_addr.ss_family,get_in_addr((struct sockaddr *)&their_addr), s, sizeof s); printf("servidor: conexao obtida de %s\n", s); // Processo filho if (!fork()) { // Processo filho nao precisa da escuta close(sockfd); ativo = 1; while(ativo){ // Recebe a opcao do client if(recv(new_fd,opt, 4, 0) == -1); perror("recv"); switch(opt[0]){ case '1': // Listar todos os Ids dos filmes com seus respectivos // titulos getAllMovieTitles(new_fd); break; case '2': // Dado o Id de um filme, retornar a sinopse getMovieSynById(new_fd, opt); break; case '3': // Dado o Id de um filme, retornar todas as informações // desse filme getMovieById(new_fd, opt); break; case '4': // Listar todas as informações de todos os filmes; getAllMovies(new_fd); break; case '5': // Finaliza conexao ativo = 0; break; default: printf("Opcao nao valida. Tente novamente\n"); break; } } close(new_fd); exit(0); } // processo pai nao precisa da nova conexao close(new_fd); } return 0; }