/* Un client */ static void* repeater(void* sck) { int sckt = (int) sck; char buf[MAX_BUFFER]; int nbc, i; const char WELCOME[] = "mtcs : bienvenu\n"; pgrs_in(); write(sckt, WELCOME, strlen(WELCOME)); pgrs("enregistrement d'une socket"); add_socket(sckt); while (1) { pgrs("attente read"); nbc = read(sckt, buf, MAX_BUFFER); if (nbc <= 0) { pgrs("fin lecture client"); pgrs("desenregistrement d'une socket"); del_socket(sckt); close(sckt); pgrs_out(); return NULL; } pgrs("boucle ecriture"); for(i=0; i<MAX_CONNECTION; i++) if (sockets[i]) write(sockets[i], buf, nbc); pgrs("fin boucle ecriture"); } return NULL; }
int main(int argc, char *argv[]) { int listen; int port = DEFAULT_PORT; struct sigaction sa; char c; sa.sa_handler = &sigusr1_handler; sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaction(SIGUSR1, &sa, NULL); /* Parse the command line */ while ((c = getopt(argc, argv, "hv")) != EOF) { switch (c) { case 'h': /* print help message */ usage(); break; case 'v': /* emit additional diagnostic info */ verbose = 1; break; default: usage(); } } pgrs("serveur initialization"); listen = open_socket(&port); printf("Server (pid %d) open on port %d\n", getpid(), port); pgrs("server loop"); while (1) { create_cnct(listen); } exit(EXIT_FAILURE); }
/* Retourne une socket d'écoute sur le port passé en argument (ce numéro de port peut etre modifié si il était déjà utilisé) */ static int open_socket(int *port) { int skfd; /* socket */ struct sockaddr_in name; int try=0; pgrs_in(); /* * « formules magiques » qui vont bien */ /* incantation créant une socket */ skfd = socket(AF_INET, SOCK_STREAM, 0); if (skfd < 0) { perror("ouverture socket ecoute"); exit(EXIT_FAILURE); } name.sin_family = AF_INET; name.sin_addr.s_addr = INADDR_ANY; name.sin_port = htons(*port); pgrs("socket creee"); /* incantation liant la socket au port souhaité */ while (try<MAX_TENTATIVE && bind(skfd, (struct sockaddr*)&name, sizeof(name)) < 0) { try++; (*port)++; name.sin_port = htons(*port); } if (try == MAX_TENTATIVE) { perror("bind de la socket"); exit(EXIT_FAILURE); } pgrs("binding effectue"); /* incantation initialisant la socket en écoute */ if (listen(skfd, MAX_PENDING) != 0) { perror("listen"); exit(EXIT_FAILURE); } pgrs("listen ok"); pgrs_out(); return skfd; } /* Notification d'un refus de connexion sur la socket */ static void noconnect(int socket) { const char NOCONNECT[] = "mtcs : connexion refusee, desole\n"; pgrs_in(); write(socket, NOCONNECT, strlen(NOCONNECT)); close(socket); pgrs_out(); } /* Etablissement, par le serveur, de la connexion d'un client */ static int create_cnct(int skfd) { int skcnct; /* socket de connection */ int status; pgrs_in(); /* on récupère la connexion */ skcnct = accept(skfd, NULL, NULL); if (skcnct < 0) { perror("ne peut etablir la connexion, accept impossible"); exit(EXIT_FAILURE); } /* un thread fils pour gérer cette connexion */ status = manage_cnct(skcnct); if (status < 0) { noconnect(skcnct); pgrs_out(); return -1; } pgrs_out(); return 0; }