/* NAME: servidor SYNOPSIS: servidor [Port_number] */ #include #include #include #include #include #include #include #include #include #include #include #define MAXHOSTNAME 80 void reusePort(int sock); int atoi(const char*); int close(int ); int EnvioDatos(int, char* ); int EchoServer(int); char *strstr(const char *, const char *); int strncmp(const char *, const char *, size_t ); char *strchr(const char *, int ); int BuscaUsuario(char*, char* ) ; ssize_t read(int, void*, size_t); char TITULO[] = "Charla Server by Jimmy Rivas R."; int sockList[64], lastSock=0; int main(int argc, char* argv[]) { int s; struct sockaddr_in server; struct sockaddr_in from; struct timeval teval; int fromlen; int length; fd_set readfds, readfdsCopy; int n,i; char message[512]; server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(INADDR_ANY); if (argc == 2) server.sin_port = htons( (u_short) atoi(argv[1])); else server.sin_port = htons((u_short) 0); s = socket (AF_INET,SOCK_STREAM,0); reusePort(s); if ( bind( s, (struct sockaddr *)&server, sizeof(server) ) ) { close(s); perror("binding name to stream socket"); exit(-1); } length = sizeof(server); if ( getsockname (s, (struct sockaddr *)&server,&length) ) { perror("getting socket name"); exit(0); } printf("\nServer Port is: %d\n", ntohs(server.sin_port)); listen(s,4); fromlen = sizeof(from); FD_ZERO(&readfdsCopy); FD_SET(s,&readfdsCopy); for(;;){ memcpy(&readfds, &readfdsCopy, sizeof(fd_set)); teval.tv_sec = 0; teval.tv_usec = 100000; n = select(FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, NULL); if (n > 0) { if (FD_ISSET(s, &readfds)) { printf("Aceptando una nueva coneccion...\n"); sockList[lastSock++] = accept(s, (struct sockaddr *)&from, &fromlen); FD_SET(sockList[lastSock-1], &readfdsCopy); /* Mensaje de bienvenida para un nuevo usuario* * */ sprintf(message,"%s\nCantidad de usuarios conectados: %d \n\n", TITULO,lastSock); EnvioDatos(sockList[lastSock-1], message); } for (i=0; i < lastSock; i++) { if (FD_ISSET(sockList[i], &readfds)) { if (EchoServer(sockList[i]) < 0) { FD_CLR(sockList[i], &readfdsCopy); sockList[i] = sockList[--lastSock]; i--; printf("Numero de clientes activos: %d\n", lastSock); } } } } if(n == 0) { sprintf(message,"<---Control del Server--->"); for (i=0; i < lastSock; i++) { EnvioDatos(sockList[i], message); } } } } int EchoServer(int psd) { char buf[512]; char *aux; char message[512]; char user_out[512]; int i,rc; /* recibe datos de clientes */ for(;;){ printf("esperando...\n"); if( (rc=read(psd, buf, sizeof(buf))) < 0) perror("receiving stream message"); if (rc > 0){ buf[rc]=(char)NULL; printf("Recibiendo de %s \n", buf); if(strstr(buf,"!quit") != (char)NULL) { /* avisar a todos que un * * usuario se ha desconectado */ BuscaUsuario(user_out,buf); sprintf(message,"#SERVER# Usuario %s desconectado...\n", user_out); for (i=0; i < lastSock; i++) { EnvioDatos(sockList[i], message); } printf("Desconectado...\n"); close (psd); return(-1); } if(strncmp("USER",buf,4) == 0){ /* avisar a todos que un nuevo * * usuario ha ingresado */ aux = (char*)strchr(buf, ':'); sprintf(message,"#SERVER# Usuario <%s> conectado...\n",++aux); for (i=0; i < lastSock; i++) { EnvioDatos(sockList[i], message); } } else { /* Enviar los datos recibidos * * a todos los usuarios */ sprintf(message,"%s",buf); for (i=0; i < lastSock; i++) { EnvioDatos(sockList[i], message); } } return(1); } else { printf("Desconectador...\n"); close (psd); return(-1); } } } int BuscaUsuario(char* line_out, char* line_in) { int l = strlen(line_in); int i; int lim = 0; for(i=0;i') lim=1; } else { break; } } line_out[i++] = '\0'; return(1); } int EnvioDatos(int psd, char* data_out) { char buf[512]; strcpy(buf,data_out); if (send(psd, buf, strlen(buf), 0) <0 ) perror("sending stream message"); return(1); } void reusePort(int s) { int one=1; if ( setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *) &one,sizeof(one)) == -1 ) { printf("error in setsockopt,SO_REUSEPORT \n");exit(-1); } }