#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include int cree_socket_stream (const char * nom_hote, const int num_port, const char * nom_proto); int affiche_adresse_socket (int sock); int serveur_tcp (void); void traite_connexion (int sock); int cree_socket_stream (const char * nom_hote, const int num_port, const char * nom_proto){ int sock; struct sockaddr_in adresse; struct hostent * hostent = NULL; struct protoent * protoent = NULL; if (nom_hote != NULL) { if ((hostent = gethostbyname(nom_hote)) == NULL) { printf("Erreur : gethostbyname\n"); return -1; } } if ((protoent = getprotobyname(nom_proto)) == NULL) { printf("Erreur : getprotobyname\n"); return -1; } // Créer la socket nommée sock if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { printf("Erreur : socket"); return -1; } // Mise à 0 de la structure adresse memset(& adresse, 0, sizeof(struct sockaddr_in)); // Donner la famille de socket dans la structure adresse adresse.sin_family = AF_INET; adresse.sin_port = num_port; // Donner un numero de port à la structure adresse if (num_port > 1024) { adresse.sin_port = htons(num_port); } else { adresse.sin_port = htons(0); } // Donner l'adresse du serveur à la structure adresse if (hostent != NULL) { adresse.sin_addr.s_addr = ((struct in_addr *) (hostent->h_addr))->s_addr; } else { adresse.sin_addr.s_addr = htonl(INADDR_ANY); } // Pattacher un port a la socket sock if (bind(sock, (struct sockaddr *) & adresse, sizeof(struct sockaddr_in)) < 0) { close(sock); printf("Erreur : bind\n"); return -1; } return sock; } int affiche_adresse_socket (int sock) { struct sockaddr_in adresse; socklen_t longueur; longueur = sizeof(struct sockaddr_in); if (getsockname(sock, & adresse, & longueur) < 0) { printf("Erreur : getsockname\n"); return -1; } printf ("IP = %s, Port = %u \n", inet_ntoa(adresse.sin_addr), ntohs(adresse.sin_port)); return 0; } int serveur_tcp (void) { int sock_contact; // Socket créée du côté du serveur int sock_connectee; // Socket du côté du client qui se connecte struct sockaddr_in adresse; socklen_t longueur; longueur = sizeof(struct sockaddr_in); // Appeler la fonction cree_socket_stream() pour créer la socket nommée socket_contact // Choisir : nom de l'hote, le num du port, le protocole sock_contact = cree_socket_stream("0.0.0.0", 1234, "tcp"); if (sock_contact < 0) { return -1; } // Placer le serveur en écoute sur la socket nommée sock_contact listen(sock_contact, 5); printf("Mon adresse >> "); affiche_adresse_socket(sock_contact); while (1) { // tester si un client se connecte : appel accept() bloquant // Le retour de accept() est une nouvelle socket nommé sock_connectee // avec laquelle l'échange avec le client aura lieu sock_connectee = accept(sock_contact, & adresse, & longueur); if (sock_connectee < 0) { printf("Erreur : accept\n"); return -1; } printf("Nouveau client\n"); switch (fork()) { case 0 : // Code du fils close(sock_contact); traite_connexion(sock_connectee); exit(EXIT_SUCCESS); case -1 : printf("Erreur : fork\n"); return -1; default : // Code du pere close(sock_connectee); } } return 0; } void traite_connexion (int sock){ char buffer[256]; int longueur; while (1) { // Lire la socket et récupérer le nombre d'octets lus dans la variable longueur longueur = read(sock, buffer, 256); if (longueur < 0) { printf("Erreur : read\n"); exit(EXIT_SUCCESS); } if (longueur == 0) { break; } // printf("J'ai lu %d bytes\n",longueur); // Pour le client telnet : //buffer[longueur-2] = '\0'; // Avec un client autre que telnet : buffer[longueur]='\0'; // printf("Je melange %s\n",buffer); //strfry(buffer); // Ecrire la variable buffer sur la socket write(sock, buffer, longueur); } close(sock); } int main (int argc, char * argv[]) { return serveur_tcp(); }