server.c 4.23 KB
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <poll.h>
#include "server.h"
#include <unistd.h>

#define MAX_LIGNE 512


int initialisationServeur(char *service,int connexions){
	struct addrinfo precisions;
	struct addrinfo *resultat;
	struct addrinfo *origine;
	int statut;
	int s;

	/* Construction de la structure adresse */
	memset(&precisions,0,sizeof precisions);
	precisions.ai_family=AF_UNSPEC;
	precisions.ai_socktype=SOCK_STREAM;
	precisions.ai_flags=AI_PASSIVE;
	statut=getaddrinfo(NULL,service,&precisions,&origine);
	if(statut<0){ perror("initialisationServeur.getaddrinfo"); exit(EXIT_FAILURE); }
	struct addrinfo *p;
	for(p=origine,resultat=origine;p!=NULL;p=p->ai_next)
	  if(p->ai_family==AF_INET6){ resultat=p; break; }

	/* Creation d'une socket */
	s=socket(resultat->ai_family,resultat->ai_socktype,resultat->ai_protocol);
	if(s<0){ perror("initialisationServeur.socket"); exit(EXIT_FAILURE); }

	/* Options utiles */
	int vrai=1;
	if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&vrai,sizeof(vrai))<0){
	  perror("initialisationServeur.setsockopt (REUSEADDR)");
	  exit(EXIT_FAILURE);
	  }
	if(setsockopt(s,IPPROTO_TCP,TCP_NODELAY,&vrai,sizeof(vrai))<0){
	  perror("initialisationServeur.setsockopt (NODELAY)");
	  exit(EXIT_FAILURE);
	  }

	/* Specification de l'adresse de la socket */
	statut=bind(s,resultat->ai_addr,resultat->ai_addrlen);
	if(statut<0) return -1;

	/* Liberation de la structure d'informations */
	freeaddrinfo(origine);

	/* Taille de la queue d'attente */
	statut=listen(s,connexions);
	if(statut<0) return -1;

	return s;

}


int boucleServeur(int ecoute,int (*traitement)(int))
{
	int dialogue;
	while(1){

	    /* Attente d'une connexion */
	    if((dialogue=accept(ecoute,NULL,NULL))<0) return -1;

	    /* Passage de la socket de dialogue a la fonction de traitement */
	    if(traitement(dialogue)<0){ shutdown(ecoute,SHUT_RDWR); return 0;}

        }
}


int serv_printf(int s){
	printf("Hello %i\n", s);
	return 0;
}


int serv_gestionClient(int s){

	/* Obtient une structure de fichier */
	FILE *dialogue=fdopen(s,"a+");
	if(dialogue==NULL){ perror("gestionClient.fdopen"); exit(EXIT_FAILURE); }

	/* Echo */
	char ligne[MAX_LIGNE];
	while(fgets(ligne,MAX_LIGNE,dialogue)!=NULL){
	  	#ifdef DEBUG
			printf("> %s", ligne);
		#endif
		fprintf(dialogue,"> %s",ligne);
	}

	/* Termine la connexion */
	fclose(dialogue);
	return 0;
}


void removeSocket(struct pollfd descr[], int i, int length){
	for (int j=i;j<length-1;j++)
	{
		descr[j]=descr[j+1];	

	}


}


int boucleServeur2(int ecoute)
{
	//initialisation tableau de socket
        //int dialogue;
	struct pollfd descripteurs[1024];
	descripteurs[0].fd=ecoute;
	//initialiser POLLIN
	for (int i=0;i<1024;i++)
	{
		descripteurs[i].events=POLLIN|POLLRDHUP|POLLERR;
	}
	int LongueurPoll = 1;

        while(1){


		//poll
		int nb = poll(descripteurs, LongueurPoll, -1);

		if(nb<0){ perror("main.poll"); exit(EXIT_FAILURE); }

		if( (descripteurs[0].revents&POLLIN) !=0){//ecoute est active
		        /* Attente d'une connexion */
		        int dialogue=accept(ecoute,NULL,NULL);
			if(dialogue<0) return -1;

			//if longueurPoll <1024 //TODO A GERER
			descripteurs[LongueurPoll].fd = dialogue;
			descripteurs[LongueurPoll].revents=0;
			LongueurPoll ++;
			printf("Nouveau LongueurPoll : %i\n", LongueurPoll);

		        /* Passage de la socket de dialogue a la fonction de traitement */
		        //if(traitement(dialogue)<0){ shutdown(ecoute,SHUT_RDWR); return 0;}
		}

		for(int i = 0; i < LongueurPoll-1; i++){
			if( (descripteurs[i+1].revents&POLLRDHUP) !=0){
				printf("|%i$ Deconnection\n", i+1);

				//FONCTION ENLEVER UN SOCKET
				removeSocket(descripteurs,i+1,LongueurPoll );
				LongueurPoll --;
			}
			else if( (descripteurs[i+1].revents&POLLIN) !=0){ //A lire
				//printf("Gestion Client %i \n", i+1);

				FILE* f = fdopen(descripteurs[i+1].fd, "a+");

				char ligne[MAX_LIGNE];
				fgets(ligne,MAX_LIGNE,f);
				printf(">%i$ %s\n", i+1, ligne);

				//renvoyer à tous les clients
				for(int j = 0 ; j < LongueurPoll-1 ; j++){
					if(j != i)
						dprintf(descripteurs[j+1].fd, ":%s\n", ligne);
				}
			}
		}

        }

}