#include #include #include #include #include #include #include #include #include #include #define BUFF_SIZE 1000 int initialisationServeur(char* service) { int sock_fd; struct addrinfo precisions, *resultat=NULL, *origine; // On stocke dans précisions nos besoins pour le socket, dans resultat l'adresse qui respectera les reqêtes memset(&precisions, 0, sizeof precisions); precisions.ai_family = AF_UNSPEC; precisions.ai_socktype = SOCK_STREAM; precisions.ai_flags = AI_PASSIVE; if(getaddrinfo(NULL, service, &precisions, &origine)<0) { fprintf(stderr, "Erreur getaddrinfo\n"); return(-1); } int n=0; for(struct addrinfo* i=origine; i!=NULL && resultat==NULL; i=i->ai_next) { printf("%d - ", n); if(i->ai_family==AF_INET) { resultat=i; printf("Test : %d", origine->ai_addrlen); } printf("\n"); n++; } struct sockaddr_in* test=(struct sockaddr_in*)(resultat->ai_addr); printf("Addr : %x\n", test->sin_addr.s_addr); if((sock_fd=socket(resultat->ai_family, resultat->ai_socktype, resultat->ai_protocol))<0) { fprintf(stderr, "Erreur socket\n"); return(-1); } int val=1; if(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR|SO_BROADCAST, &val, sizeof(val))<0) { fprintf(stderr, "Erreur setsockopt\n"); return(-1); } if(bind(sock_fd, resultat->ai_addr, resultat->ai_addrlen)) { fprintf(stderr, "Erreur bind\n"); return(-1); } if(listen(sock_fd, 20) < 0) { fprintf(stderr, "Error listen server socket\n"); return (-1); } freeaddrinfo(origine); return sock_fd; } void* reponseConnexion(void* sock) { printf("Connected\n"); char buffer[BUFF_SIZE]; FILE* sockdial_stream = fdopen(*((int*)(sock)), "a+"); printf("Sock : %d // Stream : %p \n", *((int*)(sock)), sockdial_stream); while(strcmp(buffer, "EXIT\n")!=0) { printf("WAIT\n"); fgets(buffer, BUFF_SIZE, sockdial_stream); printf("Le message reçu : %s", buffer); fprintf(sockdial_stream, "Ceci est une réponse du serveur TCP.\n"); } strcpy(buffer, "START"); printf("Fin de la connexion\n"); fclose(sockdial_stream); pthread_exit(NULL); } int lanceThread(void(* fonction) (void *), void* arg, int size) { pthread_t thr_id; if(pthread_create(&thr_id, NULL, (void*)fonction, arg )!=0) { fprintf(stderr, "Le thread n'a pas pu être créé.\n"); return -1; } pthread_detach(thr_id); return 0; } int boucleServeur(int socket, void(* fctConnex)(int)) { int sock_dial; printf("------- Début boucle serveur TCP -------\n\n"); while(1) { printf("-- boucle --\n"); if((sock_dial=accept(socket, NULL, NULL)) < 0){ fprintf(stderr, "Error accept dialogue\n"); return -1; } printf("Dialogue ACCEPTED\n"); lanceThread((void*)fctConnex, (void*)&sock_dial, sizeof(sock_dial)); } } void argPortParsing(int argc, char* argv[], char* port) { struct option port_arg={"port", 1, NULL, 'p'}; char opt; int longindex; while( (opt=getopt_long(argc, argv, "p:", &port_arg, &longindex)) !='p' && opt!=-1) {} if(opt=='p') { strcpy(port, optarg); printf("%s\n", optarg); } else { printf("La syntaxe doit être de la forme ./sioux -p ou ./sioux --port \n\n"); } } int main(int argc, char* argv[]) { char port[10]="80"; argPortParsing(argc, argv, port); int sock_fd=initialisationServeur(port); if( sock_fd==-1 ) { fprintf(stderr, "Initialisation du serveur impossible\n"); return -1; } boucleServeur(sock_fd, (void*)&reponseConnexion); return 0; }