IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

[Socket] Serveur gérant un dialogue entre plusieurs clients


Sujet :

Réseau C

  1. #61
    Membre actif Avatar de sorry60
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 802
    Points : 253
    Points
    253
    Par défaut
    C'est l'erreur 10038
    J'ai appliqué ta sémantique, ça renvoie :
    Unknown WSA error

  2. #62
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par sorry60
    C'est l'erreur 10038
    J'ai appliqué ta sémantique, ça renvoie :
    Unknown WSA error
    Oui, il faut probablement développer ce code. Je ne traite que 4 cas... Je ne vais quand même pas tout faire ?

  3. #63
    Membre actif Avatar de sorry60
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 802
    Points : 253
    Points
    253
    Par défaut
    WSAENOTSOCK

    Error Number: 10038

    Socket operation on non-socket.

    An operation was attempted on something that is not a socket.
    Either the socket handle parameter did not reference a valid
    socket, or for select, a member of an fd_set was not valid.
    Je suis pas un as de l'anglais, mais si je comprend bien, mon fds_lecture n'est pas valide
    Pourtant sous linux il est ok, et avant le select, je le remet à neuf...étrange et ennuyeux

  4. #64
    Membre actif Avatar de sorry60
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 802
    Points : 253
    Points
    253
    Par défaut
    J'ai trouvé le bug ! Enfin au moins un bug
    Quand il y a deconnexion, je fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    printf("Deconnexion de %s...\n",unClient->login);
    	  									/* On le retire de l'ensemble de lecture */
    	  									FD_CLR(unClient->fd,&fds_lecture);
    	  									/* On le retire de la liste */
    	  									retirer_client(&deb_liste,unClient->fd);
    	  									/* On ferme la socket */
    	  									closesocket(unClient->fd);
    Mais cela doit etre mal fait...
    Voici la reconsititution du fd_set, j'ai mis un printf pour savoir quelle socket est mise dedans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    FD_ZERO(&fds_lecture);
    					unClient = deb_liste;
    					while ( unClient )
    					{
    						if ( max < unClient->fd)
    						{
    							max = unClient->fd;
    						}
    						printf("Socket : %d\n",unClient->fd);
         					FD_SET(unClient->fd,&fds_lecture);
    						unClient = unClient->suivant;
    					}
    Au debut :
    Socket : 96
    C'est la socket d'ecoute qui est mise dans le fd_set..jusqu'ici tout va bien
    Ensuite, apres une connection :
    Socket : 124
    Socket : 96
    124 etant la socket du nouveau client, donc ici tout va bien aussi
    Je deconnecte le client..
    Socket : 830362444
    Socket : 96
    Et voila le bug..la socket est toujours là et surtout elle n'est plus valide !
    Donc je pense que c'est ma fonction "retirer_client" qui foire
    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    void retirer_client(client **p,SOCKET fd)
    {	
    	/* si la liste est vide */
    	if ( !p )
    	{
    		/* rien à  faire...*/
    		return;
    	}
    	else
    	{
    		/* si la liste ne contient qu'un seul élément */
    		if ( !((*p)->suivant) )
    		{
    			/* on libère l'element */
    			free(*p);
    			/* on fait pointer la liste sur NULL */
    			p = NULL;
    			return;
    		}
    		else
    		{
    			client *prec = malloc(sizeof (client));
     
    			if ( prec )
    			{	
    				/* sinon on parcourt la liste jusqu'au bon client*/
    				while ( p && ((*p)->fd != fd) )
    				{
    					/* on sauvegarde l'element precédent */
    					prec = *p;
    					/* on passe au client suivant */
    					*p = (*p)->suivant;
    				}
    				/* on saute l'element bientot supprimé */
    				prec->suivant = (*p)->suivant;
    				/* on supprime l'element */
    				free(*p);
    				/* le client precedent devient le client actuel */
    				*p = prec;
    			}
    			else
    			{
    				perror("malloc()");
    			}
    		}
    	}
    }

  5. #65
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par sorry60
    WSAENOTSOCK

    Error Number: 10038

    Socket operation on non-socket.

    An operation was attempted on something that is not a socket.
    Either the socket handle parameter did not reference a valid
    socket, or for select, a member of an fd_set was not valid.
    hé hé, fichier complété...

  6. #66
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    sorry60 -> En fait, elle est très mauvaise... Je vais essayer de corriger...
    Edit: Voilà une fonction corrigée:
    (Je l'ai compilée en -ansi, mais je ne l'ai pas testée)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    /* Fonction pour retirer un client de la liste chaînée
       --------------------------------------------------- */
    /* Retourne 0 si succès, -1 si erreur (convention lib standard) */
    int retirer_client(
     client **pt_pt_client /*[in/out]Liste chaînée à modifier*/,
     SOCKET sock /*[in]Socket du client à retirer de la liste*/
     )
    {
    client *pt_client = NULL;
     
    /* Si la liste est inexistante, on quitte */
    if( pt_pt_client==NULL )
    	return -1;
     
    pt_client = *pt_pt_client;
     
    /* si la liste est vide, on quitte aussi */
    if ( pt_client==NULL )
    return 0;
     
    /* si la liste ne contient qu'un seul élément */
    if ( pt_client->suivant==NULL )
    	{
    	/* on libère l'element */
    	free(pt_client);
    	/* on fait pointer la liste sur NULL */
    	/* Médinoc : ERREUR: tu ne modifies pas le pointeur de l'utilisateur...
    	p = NULL;
    	*/
    	*pt_pt_client = NULL;
    	return 0;
    	}
     
    /* Médinoc : ??
      Pourquoi une allocation dans une fonction pour retirer?
    client *prec = malloc(sizeof (client));
    */
     
    /* sinon on parcourt la liste jusqu'au bon client.
    Au fur et à mesure, on actualise pt_pt_client
    pour savoir quel pointeur changer lors de la suppression */
    while ( pt_client )
    	{
    	/* Si l'élément contient le socket à retirer, on le retire et on quitte */
    	if(pt_client->fd == sock)
    	    {
    		/* On fait pointer le client précédent (ou le début de liste)
    		sur le client suivant (qui peut être NULL) */
    		*pt_pt_client = pt_client->suivant;
    		/* On supprime le client de la mémoire */
    		free(pt_client);
    		/* On quitte */
    		break;
    		}
    	/* On actualise le pointeur de pointeur */
    	pt_pt_client = &(pt_client->suivant);
    	/* On passe au client suivant */
    	pt_client = pt_client->suivant; /* ou pt_client = *pt_pt_client; */
    	}
    return 0;
    }
    Emmanuel : Sous Windows, pourquoi ne pas utiliser FormatMessage() pour tes messages d'erreur ? (Oui, ça marche aussi avec Winsock).


    PS: Ce serait bien si la balise code pouvait parser les comentaires...

  7. #67
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Médinoc
    Sous Windows, pourquoi ne pas utiliser FormatMessage() pour tes messages d'erreur ? (Oui, ça marche aussi avec Winsock).
    Ben oui, je me le demande encore.... Bonne idée.

  8. #68
    Membre actif Avatar de sorry60
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 802
    Points : 253
    Points
    253
    Par défaut
    Voila, apres m'etre exercé sur les listes chainées, j'ai pu corriger mon code.
    Maintenant, il a l'air de bien fonctionner, je le post, si jamais ça interesse quelqu'un, ou si vous voulez faire des remarques.

    serveur.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #ifndef H_SERVEUR
     
    #define H_SERVEUR
     
     
    #if defined(__linux)
    #   define SOCKET_ERROR -1
     
    #   define INVALID_SOCKET -1
     
    #   define closesocket(s) close(s)
     
    #	 define SOCKET int
     
    #endif
     
     
     
    #define LOGIN_SIZE 16
     
    #define MDP_SIZE 16
     
    #define PORT 4000
     
     
     
    /* ******************************************************************************************* */
     
    /* *********************************** Couche liste ****************************************** */
     
     
     
    /* Structure représentant un client */
     
    	typedef struct client
     
    	{
     
    		char login[LOGIN_SIZE ];
     
    		char passwd[MDP_SIZE];
     
    		SOCKET fd;
     
    		struct client* pSuivant;
     
    	}client;
     
    /* Structure de liste */
     
    	typedef struct list
     
    	{
     
    		struct client* pTete;
     
    		struct client* pQueue;
     
    	}list;
     
    /* Fonction qui ajoute un client au debut la liste */
     
    	void ajouter_client (list *p, char log[LOGIN_SIZE], char mdp[MDP_SIZE ], SOCKET fd);
     
     
     
    /* Fonction qui retire un client de la liste */
     
    	void retirer_client(list *p,SOCKET fd);
     
     
     
    /* Fonction qui affige le login de tous les clients de la liste*/
     
    	void afficherListe(list *p);
     
     
     
    /* Fonction qui vide la mémoire occupée par le liste */
     
    	void clear_clients(list *);
     
     
     
    /* ******************************************************************************************* */
     
    /* ******************************************************************************************* */
     
     
     
    /* ******************************************************************************************* */
     
    /* ********************************* Couche Serveur ****************************************** */
     
    /* Fonction qui authentifie un utilisateur */	
     
       int authentification(char user[]);
     
     
     
    /* ******************************************************************************************* */
     
    /* ******************************************************************************************* */
     
    #endif
    fonctions_liste.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #ifdef __cplusplus
     
    #error Be sure you are using a C compiler...
     
    #endif
     
     
     
    #include "serveur.h"
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
     
     
     
    /* ********************************************************************************************************************** */
     
    void ajouter_client (list *p, char log[LOGIN_SIZE], char mdp[MDP_SIZE ], SOCKET fd)
     
    {
     
    	client *nouv = malloc(sizeof(*nouv));
     
    	if(nouv)
     
    	{
     
    		memcpy(nouv->login,log,LOGIN_SIZE);
     
    		memcpy(nouv->passwd,mdp,MDP_SIZE);
     
    		nouv->fd = fd;
     
    		/* Si la liste est vide */
     
    		if( !p->pTete )
     
    		{
     
    			/* Le nouvel element est à la fois tete et queue */
     
    			p->pTete = nouv;
    			p->pTete->pSuivant = NULL;
     
    			p->pQueue = nouv;
    			p->pQueue->pSuivant = NULL;
     
    		}
     
    		else
     
    		{
     
    			nouv->pSuivant = p->pTete;
    			p->pTete = nouv;
     
    		}
     
    	}
     
    	else
     
    	{
     
    		perror("malloc()");
     
    		exit (1);
     
    	}
     
    } 
     
    /* ********************************************************************************************************************** */
     
    void retirer_client(list *p,SOCKET fd)
     
    {	
     
       /* Si la liste ne contient qu'un element */
     
       if ( (!p->pTete->pSuivant) && (p->pTete->fd == fd) )
     
       {
     
    		free(p->pTete);
     
    		p->pTete = NULL;
     
    		p->pQueue = NULL;
     
    		return;
     
    	}
     
    	/* Si l'element a supprimer est en tete de liste */
     
    	if( p->pTete->fd == fd )
     
    	{
     
    		client *tmp = p->pTete->pSuivant;
     
    		free(p->pTete);
     
    		p->pTete = tmp;
     
    		return;
     
    	}
     
    	/* Sinon */
     
    	{
     
    		client *prec = p->pTete;
     
    		client *tmp = p->pTete;
     
     
     
    		/* On se positionne sur l'element a supprimer */
     
    		while( (tmp) && (tmp->fd != fd) )
     
    		{
     
    			prec = tmp;
     
    			tmp = tmp->pSuivant;
     
    		}
     
    		if ( tmp )
     
    		{
     
    			/* Si l'element est en queue de liste */
     
    			if ( p->pQueue == tmp )
     
    			{
     
    				free(p->pQueue);
     
    				p->pQueue = prec;
     
    				p->pQueue->pSuivant = NULL;
     
    			}
     
    			else
     
    			{
     
    				prec->pSuivant = tmp->pSuivant;
     
    				free(tmp);
     
    				tmp = prec;
     
    			}
     
    		}
     
    		else
     
    		{
     
    			printf("Cet element n'est pas dans la liste.\n");
     
    		}
     
    	}
     
    }
     
    /* ********************************************************************************************************************** */
    void afficherListe(list *p)
    {
    	client *tmp = p->pTete;
     
    	while(tmp)
    	{
    		printf("%s : %d\n",tmp->login,tmp->fd);
    		tmp = tmp->pSuivant;
    	}
    }
    fonctions_serveur.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #ifdef __cplusplus
     
    #error Be sure you are using a C compiler...
     
    #endif
     
     
     
    #include "serveur.h"
    #include <stdio.h>
    #include <string.h>
     
     
     
    /* ********************************************************************************************************************** */
     
    /* Fonction qui authentifie le client qui tente de se connecter */
     
    /* Revoie 0 si authentification reussie, 404 si l'utilisateur est inconnu, ou 1 en cas d'erreur */
     
    int authentification(char user[])
     
    {
     
    	FILE* FP;
     
      	int err = 0;
     
     
     
      	/*Ouverture du fichier contenant les utilisateurs */
     
      	FP = fopen("./users.txt","r");
     
      	if ( FP != NULL )
     
      	{
     
       	char buf[256];
     
        	char user_courant[128];
     
        	int eof = 0;
     
        	do
     
        	{
     
          	if ( fgets(buf,sizeof buf,FP) == NULL )
     
          	{
     
    				eof = 1;
     
          	}
     
          	else
     
          	{
     
    				sscanf(buf,"%s",user_courant);
     
          	}
     
        	}
     
        	while ( (eof == 0) && (strcmp(user,user_courant) != 0));
     
        	if ( eof == 0 )
     
        	{
     
          	printf("%s vient de se connecter...\n",user_courant);
     
        	}
     
        	else
     
        	{
     
          	printf("Utilisateur inconnu !\n");
     
          	err = 404;
     
        	}
     
      	}
     
      	else
     
      	{
     
       	perror("fopen()");
     
        	err = 1;
     
      	}
     
      	return err;
     
    }
     
    /* Fin de la fonction d'authentification */
     
    /* ********************************************************************************************************************** */
    princ.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #ifdef __cplusplus
    #error Be sure you are using a C compiler...
    #endif
     
    #if defined(_WIN32)
     
    #   include <windows.h>
     
    #elif defined(__linux)
     
    #   include <sys/socket.h>
     
    #   include <arpa/inet.h>
    #else
     
    #error not defined for this platform
     
    #endif
     
     
     
    #include <sys/types.h>
     
    #include <sys/time.h>
     
    #include <unistd.h>
     
    #include <stdio.h>
    #include "serveur.h"
     
    /* ************************************************************************************************************************* */
    int main()
    {
    #if defined (_WIN32)
    	WSADATA wsa_data;
      	if ( WSAStartup(MAKEWORD(2,2),&wsa_data) != 0 )
      	{
        	perror("WSAStartup()");
        	return 1;
      	}
    #endif
    	list lesClients;
      	int err = 0;
      	SOCKET max = 0;
      	SOCKET s_ecoute;
      	/*Ensemble de socket surveillées en lecture */
      	fd_set fds_lecture;
      	FD_ZERO(&fds_lecture);
      	lesClients.pTete = NULL;
      	lesClients.pQueue = NULL;
      	printf("La liste au debut :\n");
      	afficherListe(&lesClients);
     
      	/* Création de la socket */
      	s_ecoute = socket(PF_INET,SOCK_STREAM,0);
      	max = s_ecoute;
      	if ( s_ecoute != INVALID_SOCKET )
      	{
       	/* "bindage" de la socket */
        	struct sockaddr_in myaddr;
        	struct sockaddr_in client_addr;
     
        	myaddr.sin_family = AF_INET;
        	myaddr.sin_port = htons(PORT);
        	myaddr.sin_addr.s_addr = (INADDR_ANY);
        	err = bind(s_ecoute,(struct sockaddr *) &myaddr, sizeof (myaddr));
        	if ( err != SOCKET_ERROR )
        	{
    			/* Ecoute sur le port */
    			printf("Attente de connexion sur le port %d...\n",PORT);
    			err = listen(s_ecoute,10);
    			if ( err != SOCKET_ERROR )
    			{
    				/* On met la socket d'ecoute dans l'ensemble de lecture */
    				FD_SET(s_ecoute,&fds_lecture);
    				/* On ajoute la socket d'ecoute dans la liste */
    	  			ajouter_client(&lesClients,"","",s_ecoute);
    				while(1)
    				{
    					printf("La liste au debut du while(1) :\n");
    				  	afficherListe(&lesClients);
    					client *tmp = lesClients.pTete;
    					/* on reconstitue le fds_lecture */
    					FD_ZERO(&fds_lecture);
    					while (tmp)
    					{
    						printf("La liste au debut du while(tmp) :\n");
    					  	afficherListe(&lesClients);
    						if ( max < tmp->fd)
    						{
    							max = tmp->fd;
    						}
         					FD_SET(tmp->fd,&fds_lecture);
    						tmp = tmp->pSuivant;
    					}
    	  				if ( select(max+1,&fds_lecture,NULL,NULL,NULL) != -1 )
    	  				{
    	  					/* On se repositionne en debut de liste et on la parcourt */
    						tmp = lesClients.pTete;
    	  					while( tmp )
    	  					{
    	  						/* Si il sait passer quelque chose dans l'emsemble de lecture avec ce client */
    	  						if ( FD_ISSET(tmp->fd,&fds_lecture))
    	  						{
    	  							/* Si c'est la socket d'ecoute ==> nouvelle connexion ! */
    	  							if ( tmp->fd == s_ecoute )
    	  							{
    	  								unsigned int size_client_addr = sizeof(client_addr);
    	  								SOCKET newClient = accept(s_ecoute,(struct sockaddr *)&client_addr,&size_client_addr);
    	  								int oct_rec;
    	  								if ( newClient != INVALID_SOCKET )
    	  								{
    	  									char login[LOGIN_SIZE];
    	  									printf("Connexion d'un nouveau client : %s socket : %d...\n",inet_ntoa(client_addr.sin_addr),newClient);
    	  									/* On attend la réception de son login */
    	  									oct_rec = recv(newClient,login,sizeof(login),0);
    	  									if ( oct_rec != - 1)
    	  									{
    	  										/* On procède à  l'authentification du login */
    	  										int authent = authentification(login);
    	  										if ( authent == 0 )
    	  										{
    	  											/* Authentification reussie ! */
    	  											/* On met le nouveau client dans la liste */
    	  											ajouter_client(&lesClients,login,"",newClient);
    	  											/* On le met aussi dans l'ensemble de lecture */
    	  											FD_SET(newClient,&fds_lecture);
    	  										}
    	  										else
    	  										{
    	  											/* Client inconnu ! */
    	  											char erreur404[] = "Desole vous n'etes pas dans la base de donnees...\n";
    	  											int oct_env;
    	  											/* On envoie un message d'erreur au client inconnu */
    	  											oct_env = send(newClient,erreur404,sizeof(erreur404),0);
    	  											if ( oct_env == -1 )
    	  											{
    	  												perror("send() 404error");
    	  											}
    	  											/* On ferme la socket */
    	  											closesocket(newClient);
    	  										}
    	  									}
    	  									else
    	  									{
    	  										perror("revc() login");
    	  									}
    	  								}
    	  								else
    	  								{
    	  									perror("accept()");
    	  								}
    	  							}
    	  							else
    	  							{
    	  								/* Le client en cours a fait une action ! */
    	  								printf("Action de %s !\n",tmp->login);
    	  								int oct_rec;
    	  								char message[144];  /* 16 premiers octets pour le login du destinataire, le reste c'est le message */
     
    	  								oct_rec = recv(tmp->fd,message,sizeof(message),0);
    	  								if ( oct_rec <= 0 )
    	  								{
    	  									/* Erreur ou deconnexion client */
    	  									printf("Deconnexion de %s...\n",tmp->login);
    	  									/* On ferme la socket */
    	  									closesocket(tmp->fd);
    	  									/* On le retire de l'ensemble de lecture */
    	  									FD_CLR(tmp->fd,&fds_lecture);
    	  									/* On le retire de la liste */
    	  									retirer_client(&lesClients,tmp->fd);
    	  								}
    	  								else
    	  								{
    	  									/* Le client a envoye un message ! */
    	  									printf("%s a envoyé %d octets !\n",tmp->login,oct_rec);
    	  								}
    	  							}
    	  						}
    	  						tmp = tmp->pSuivant;
    	  					} /* Fin du parcour de la liste */
    	  				}
    	  				else
    	  				{
    	  					perror("select()");
    	  				}
    	  			} /* Fin de la boucle infinie */
    	  		}
    			else
    			{
    	  			perror("listen()");
    			}
        	}
        	else
        	{
          	perror("bind()");
        	}
      	}
      	else
      	{
       	perror("socket()");
        	err = 1;
      	}
    #if defined (_WIN32)
    	WSACleanup();
    #endif
    	return err;
    }
    /* ********************************************************************************************************************** */

  9. #69
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par sorry60
    Voila, apres m'etre exercé sur les listes chainées, j'ai pu corriger mon code.
    Tu devrais maintenant travailler à la généricité du code, c'est à dire à le rendre indépendant des données. (En gros, un void* suffit).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct node
    {
       void *p_data
       struct node *p_next;
    };
    Mais une petite partie des traitements doit alors être confiée à l'appelant sous forme de callbacks (comme fait qsort()).

  10. #70
    Membre actif Avatar de sorry60
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 802
    Points : 253
    Points
    253
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Citation Envoyé par sorry60
    Voila, apres m'etre exercé sur les listes chainées, j'ai pu corriger mon code.
    Tu devrais maintenant travailler à la généricité du code, c'est à dire à le rendre indépendant des données. (En gros, un void* suffit).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct node
    {
       void *p_data
       struct node *p_next;
    };
    Mais une petite partie des traitements doit alors être confiée à l'appelant sous forme de callbacks (comme fait qsort()).
    Le *void pointrait un coup sur un SOCKET, un coup sur un char[] c'est ça ?
    Je vais regarder dans le K&R si il y a un chapitre dessus

  11. #71
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par sorry60
    Le *void pointrait un coup sur un SOCKET, un coup sur un char[] c'est ça ?
    Par exemple. Evidemment, la durée de vie de l'objet pointé doit être >= à celle de la liste...
    Je vais regarder dans le K&R si il y a un chapitre dessus
    Pas la peine !

  12. #72
    Membre actif Avatar de sorry60
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 802
    Points : 253
    Points
    253
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Citation Envoyé par sorry60
    Je vais regarder dans le K&R si il y a un chapitre dessus
    Pas la peine !
    Arf..ça va être dur sans cours et exemple

  13. #73
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par sorry60
    Arf..ça va être dur sans cours et exemple
    Un exemple standard : qsort()...

    Sinon voir ça :

    http://emmanuel-delahaye.developpez.com/complog.htm

    et ça:

    http://emmanuel-delahaye.developpez.com/tad.htm

Discussions similaires

  1. Plusieurs socket cliente sur une socket serveur en Java?
    Par loic911 dans le forum Développement
    Réponses: 3
    Dernier message: 11/06/2010, 07h47
  2. Dialogue entre serveur et client
    Par Carrel dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 03/07/2009, 06h48
  3. problème lors d'un dialogue entre client et serveur
    Par Dave62 dans le forum Réseau
    Réponses: 3
    Dernier message: 10/12/2008, 09h24
  4. Réponses: 3
    Dernier message: 31/10/2006, 10h34
  5. [Socket] Probleme entre un Client C et un serveur JAVA
    Par bpy1401 dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 28/02/2006, 08h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo