1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
| #define NB_MAX_PENDANTES 10
#define NB_MAX_CLIENTS 10
#define TAILLE 128
int main(int argc, char *argv[])
{
char *adrSnom;
int nport, soc_ec, i, max_soc, soc_libre;
int soc_service[NB_MAX_CLIENTS]; // tableau de sockets de service
int res;
fd_set set;
int k, n;
struct sockaddr_in adrC, adrS;
struct hostent *hp;
if(argc != 3)
{
fprintf(stderr, "Usage : %s adrSnom nport\n", argv[0]);
exit(1);
}
adrSnom = argv[1];
nport = atoi(argv[2]);
/* Creation d'une socket domaine Internet et mode connecte */
soc_ec = socket(AF_INET, SOCK_STREAM, 0);
if(soc_ec < 0)
{
perror("socket ip");
exit(1);
}
/* Creation adresse serveur */
adrS.sin_family = AF_INET;
adrS.sin_port = htons(nport); /* 0 pour attribution d'un port libre */
/*printf("Resolution adresse serveur...\n");*/
hp = gethostbyname(adrSnom);
if(hp == NULL)
{
herror("gethostbyname ip");
close(soc_ec);
exit(1);
}
memcpy(&adrS.sin_addr.s_addr, hp->h_addr, hp->h_length);
/* Attachement de la socket a l'adresse du serveur */
if(bind (soc_ec, (struct sockaddr *) adrS, sizeof(struct sockaddr_in))==-1)
{
perror("bind\n");
close(soc_ec);
exit(1);
}
/* Recuperation du port sous forme Network */
if(getsockname (soc_ec, (struct sockaddr *) adrS, &adrlen)<0)
{
perror("getsockname ip");
close(soc_ec);
exit(1);
}
printf("Port %d ouvert\n", ntohs(adrS.sin_port));
printf("Serveur : transformation socket en socket d'ecoute...\n");
/* Transformation de la socket en socket d'ecoute */
if(listen(soc_ec, NB_MAX_PENDANTES) == -1)
{
perror("listen");
close(soc_ec);
exit(1);
}
/* Initialisation : pour le moment le descripteur max est soc_ec */
max_soc = soc_ec;
soc_libre = 0; //L'indice du 1er emplacement de libre dans le tableau de sockets est 0
/* Initialisation du tableau de sockets de service */
for(i=0; i<NB_MAX_CLIENTS; i++)
soc_service[i] = -1;
while(1)
{
printf("Serveur : en attente de connexions...\n");
FD_ZERO(&set);
FD_SET(soc_ec, &set);
printf("Dans le while\n");
/* On scrute parmi les sockets de service presentes dans le tableau */
for(i=0; i<NB_MAX_CLIENTS; i++)
if(soc_service[i] >= 0)
FD_SET(soc_service[i], &set);
printf("Avant le select\n");
res = select(max_soc+1, &set, NULL, NULL, NULL);
if(res<0) {perror("select"); goto fin_serveur;}
if(res>0)
{
printf("Apres le select\n");
/* Si la socket d'ecoute est prete et qu'il y a des sockets de service libres : acceptation d'un nouveau client*/
if( FD_ISSET(soc_ec, &set) && soc_libre < NB_MAX_CLIENTS )
{
socklen_t adrlen = sizeof(struct sockaddr_in);
soc_service[soc_libre] = accept(soc_ec, (struct sockaddr *) adrC, &adrlen);
if(soc_service[soc_libre]<0) {perror("accept"); goto fin_serveur;}
//Mise a jour du fd max parmi les sockets de service (pour le select)
if(max_soc < soc_service[soc_libre])
max_soc = soc_service[soc_libre];
printf("Serveur : connexion etablie...\n");
//Mise a jour de l'indice soc_libre -> trouver un emplacement de libre dans le tableau
for(i=0; i<NB_MAX_CLIENTS; i++)
if(soc_service[i]<0) //des que un emplacement libre
break; //sortir de ce for
printf("Apres le 1er for\n");
//Si cet indice vaut NB_MAX_CLIENTS, alors il n'y a plus aucune place de libre
if(i == NB_MAX_CLIENTS)
{
printf("Serveur : pile des clients pleine\n");
soc_libre = NB_MAX_CLIENTS;
continue;
}
//Recuperation de cet indice
soc_libre = i;
printf("La valeur de soc_libre = %d\n", soc_libre);
//Recherche de l'indice d'une socket de service prete
/*** PROBLEME : IL N'Y A JAMAIS DE SOCKETS DE SERVICE QUI SOIENT ELIGIBLES ! ***/
for(i=0; i<NB_MAX_CLIENTS; i++)
{
printf("---- [i=%d] for additionnel\n",i);
if(soc_service[i]!=-1 && FD_ISSET(soc_service[i], &set))
printf("FD_ISSET pour i=%d\n", i);
else
printf("pas de FD_ISSET i=%d\n", i);
}
printf("Sortie du for additionnel\n");
i=0;
while(i<NB_MAX_CLIENTS)
{
if(soc_service[i]!=-1 && FD_ISSET(soc_service[i], &set))
break;
else i++;
}
/*** DU COUP ICI : i=NB_MAX_CLIENTS ***/
printf("Apres recherche : i = %d\n", i);
/* Si aucune n'est prete : on continue (bouclera jusqu'a ce qu'il y en ai une de prete) */
if(i==NB_MAX_CLIENTS)
{
printf("------ Aucune n'est prete\n");
continue;
}
/*** ET ALORS LE PROGRAMME REMONTE AU WHILE POUR ATTENDRE QU'IL Y EN AIT UNE QUI SOIT ELIGIBLE : IL SE BLOQUE***/
printf("Avant le FD_ISSET\n");
if(soc_service[i]!=-1 && FD_ISSET(soc_service[i], &set))
{
printf("Serveur : Traitement de la requete...\n");
(...)
//Une fois la requete traitee pour ce client : liberation de l'emplacement correspondant dans le tableau
soc_service[i] = -1;
if(soc_libre == NB_MAX_CLIENTS) //Si plus de place libre
soc_libre = i; //Une place vient de se liberer
}
} /* Fin du if( FD_ISSET(soc_ec, &set) && soc_libre < NB_MAX_CLIENTS ) */
}/*fin du if(res>0)*/
}/* Fin du while(1) */
fin_serveur : printf("Serveur : fin du serveur, fermeture sockets...\n");
close(soc_ec);
/* Fermeture de toutes les sockets de service */
for(i=0; i<NB_MAX_CLIENTS; i++)
close(soc_service[i]);
exit(0);
} |
Partager