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 :

Liste chainée, sockets, serveur multi clients.


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de jbarreau-mainson
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 446
    Par défaut Liste chainée, sockets, serveur multi clients.
    Bonjour à tous,

    je tente actuellement d'améliorer le fonctionnement d'un serveur multi clients que j'ai réalisé il y a peu en gérant mes clients par liste chainée.

    Ca me permet de ne pas avoir un nombre de clients limités et puis ca me fait bosser un peu ^^

    J'utilise la fonction select pour gérer la communication/connection/deconnection de mes clients avec le serveur.
    Seulement sur ce point je bloque quelque peu.

    Voici mon code :

    //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
    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
    #include "appli.h"
     
    t_serveur serveur;
    WSADATA wsaData;
     
    char Buff[BUFF_SIZE];
    int max, clean;
     
    int Serveur(int sc, int pa)
    {
        switch(sc)
        {
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Constructeur. Service NEW pour Serveur.
    //Création du serveur.
            case SERVEUR_NEW :
                //Initialisation de la DLL permettant d'utiliser les sockets.
                if(WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
                {
                    Fin("Initialisation DLL Wsa : Echec.\n");
                }
                //Création de la Socket serveur : Protocole IPv4, Flux de données binaires, Protocole TCP ( mode "connecté")
                if((serveur.Sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
                {
                    Fin("Echec lors de la création de la Socket serveur.\n");
                }
     
                //Remplissage de la structure concernant les informations de la Socket
                serveur.Sin.sin_family       = PF_INET;              //Protocole IPv4
                serveur.Sin.sin_addr.s_addr  = htonl(INADDR_ANY);    //Ecoute toutes les adresses IP
                serveur.Sin.sin_port         = htons(PORTSQL);       //Port du serveur
     
                //Liaison de la Socket serveur avec la structure Sockaddr
                //La structure contenant les informations est Sockaddr_in, nous faisons donc un cast
                if(bind(serveur.Sock, (SOCKADDR *)&serveur.Sin, sizeof(serveur.Sin)) == SOCKET_ERROR)
                {
                    Fin("Echec du bind.\n");
                }
     
                //Attente de connexions sur la socket serveur
                if(listen(serveur.Sock, 0) == SOCKET_ERROR)
                {
                    Fin("Echec de l'écoute sur la Socket.\n");
                }
     
                //Création des clients.
                t_client *clients = NULL;
     
                //Ensemble de descripteurs de fichier.
                fd_set readfds;             //Ici, cet ensemble sera examiné si des données sont disponibles en lecture à partir de l'un
                                            //de ses descripteurs de fichiers.
                max = serveur.Sock;
                serveur.Cpass = "Admin";    //Password pour l'authentification des clients.
     
                break;
     
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Service RUN pour Serveur.
            case SERVEUR_RUN :
                for(;;)
                {
                    FD_ZERO(&readfds);
                    FD_SET(serveur.Sock, &readfds);
     
                    t_client *now = clients;
     
                    while(now != NULL) // on ajoute les descripteurs des fichiers ouverts à l'ensemble fd_set
                    {
                        FD_SET(now->Sock, &readfds) ;
                        //printf("%d\n", courant->s);
                        now = now->suivant ;
                    }
     
                    if(select(max+1, &readfds, NULL, NULL, NULL) == -1)
                    {
                        Fin("Erreur lors du select().");
                    }
     
                    if(FD_ISSET(serveur.Sock, &readfds))
                    {
                        //Nouveau Client
                        serveur.Sinsize = sizeof(serveur.Csin);
                        serveur.Csock = accept(serveur.Sock, (SOCKADDR *)(&(serveur.Csin)), &(serveur.Sinsize));
                        if(serveur.Csock == INVALID_SOCKET)
                        {
                            Logs("Echec de la connection du client.\n");
                        }
     
                        now->Sock = serveur.Csock;
     
                        if(now->Sock > max)
                        {
                            max = now->Sock;
                        }
     
                        //Authentification du client
                        purge(Buff);
                        recv(now->Sock, Buff, sizeof(Buff) - 1, 0);
     
                        //La fonction strcmp compare deux chaines Buff et serveur.Cpass et renvoie un entier négatif, nul,
                        //ou positif, si Buff est respectivement inférieure, égale ou supérieure à serveur.Cpass.
                        if((strcmp(Buff, serveur.Cpass) != 0))
                        {
                            purge(Buff);
                            strcpy(Buff, "Bad password !");
                            send(now->Sock, Buff, (int)strlen(Buff), 0);
                            closesocket(now->Sock);
                            purge(Buff);
                            printf("Mauvais password pour (N.%d) %s.\n", now->Sock, inet_ntoa(serveur.Csin.sin_addr));
                        }
     
                        else
                        {
                            printf("Nouvelle connexion (n.%d) : %s se connecte.\n", now->Sock, inet_ntoa(serveur.Csin.sin_addr));
                            strcpy(Buff, "-- Bienvenue sur le serveur SQL");
                            send(now->Sock, Buff, (int)strlen(Buff), 0);
                            purge(Buff);
                            Client(CLIENT_NEW, &clients, 0);
                        }
                    }
     
                    now = clients;
     
                    while(now != NULL)
                    {
                        if(FD_ISSET(now->Sock, &readfds))
                        {
                            if(recv(now->Sock, Buff, sizeof(Buff) - 1, 0) == SOCKET_ERROR)
                            {
                                printf("Deconnection (N.%d) de %s.\n", now->Sock, inet_ntoa(serveur.Csin.sin_addr));
                                closesocket(now->Sock);
                                Client(CLIENT_SUPPR, now, 0);
                            }
                            //Reception
                            else
                            {
                                printf("%s dit : %s\n", inet_ntoa(serveur.Csin.sin_addr), Buff);
                                purge(Buff);
                            }
     
                            //Envoi
                            strcpy(Buff, "Message.\n");
                            send(now->Sock, Buff, (int)strlen(Buff), 0);
                            purge(Buff);
                        }
                        now = now->suivant;
                    }
                }
                break;
     
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Destructeur. Service DEL pour Serveur.
            case SERVEUR_DEL :
                closesocket(serveur.Sock);   //Fermeture de la Socket serveur.
                WSACleanup();                //Libération de la dll.
                break;
     
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            default :
                Fin("SERVEUR_*** : bad sc");
                break;
        }
        return 0;
    }
     
    void purge(char *Buff)
    {
        for(clean = 0; clean < BUFF_SIZE; clean++)
        {
            Buff[clean] = '\0';
        }
    }
    //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
    #define SERVEUR_NEW 203
    #define SERVEUR_RUN 204
    #define SERVEUR_DEL 205
    #define SERVEUR_ACCESS 206
     
    #define BUFF_SIZE 1024
    #define PORTSQL 10000
     
    typedef struct tt_serveur {
        SOCKET Sock;
        SOCKADDR_IN Sin;
        SOCKET Csock;
        SOCKADDR_IN Csin;
        size_t Sinsize;
        char *Cpass;
    }t_serveur;
     
    int Serveur(int sc, int pa);
    void purge(char *Buff);
    //Client.c (contenu dans le projet serveur ...)
    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
    #include "appli.h"
     
    int Client(int sc, t_client **p, int pa)
    {
        switch(sc)
        {
     
    /******************************************************************************************************************************/
    //Constructeur. Service NEW pour Client.
    //Création d'un nouveau client.
            case CLIENT_NEW:
                puts("");
                t_client *client = malloc(sizeof(t_client)); //Création d'un nouveau client.
                if(!client)
                {
                    Fin("CLIENT_NEW : malloc a échoué");
                }
                client->Valeur = pa;   //Affectation de la valeur au client.
                client->suivant = *p;     //Adresse du client suivant.
                *p = client;          //Le pointeur pointe sur le dernier client.
                break;
     
    /******************************************************************************************************************************/
    //Service ENUM pour Client.
    //Liste le nombre de clients
            case CLIENT_ENUM:
                pa = 0;
                while(p)
                {
                    pa++;
                    p = p->suivant;
                }
                printf("Il y a actuellement %d clients de connectés.\n", pa);
                break;
     
    /******************************************************************************************************************************/
    //Service SUPPR pour Client.
    //Enlève un client de la liste.
            case CLIENT_SUPPR:
                puts("");
                int Val;
                t_client *temp;
     
                if(!*p)
                {
                    return -1;      //Il n'y a plus de clients.
                }
     
                temp = (*p)->suivant;
                Val = (*p)->Valeur;
                free(*p);           //Libération de la mémoire allouée au pointeur.
                *p = temp;          //Le pointeur pointe sur le dernier client.
                closesocket(pa->Sock);
                return Val;
                break;
     
    /******************************************************************************************************************************/
    //Service DEL pour Client.
    //Destructeur. Supprime tous les clients.
            case CLIENT_DEL:
                t_client *temp;
     
                while(*p)
                {
                    temp = (*p)->suivant;
                    free(*p);
                    *p = temp;
                    closesocket(temp.Sock);
                }
                break;
     
    /******************************************************************************************************************************/
            default:
                Fin("CLIENT_*** : bad sc");
                break;
     
    /******************************************************************************************************************************/
        }
        return 0;
    }
    //Client.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #define CLIENT_NEW 200
    #define CLIENT_ENUM 201
    #define CLIENT_SUPPR 202
    #define CLIENT_DEL 203
     
    typedef struct tt_client{
        int Valeur;
        struct t_client *suivant;
        SOCKET Sock;            //Socket Client
    }t_client;
     
    int Client(int sc, t_client **p, int pa);
    Je crois qu'il y a quelques incohérence avec la liste chainée, mais je débute sur ce chapitre !

  2. #2
    Membre éprouvé Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par défaut
    Bonjour,

    au niveau de la déclaration de la structure, non du type pardon :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #define CLIENT_NEW 200
    #define CLIENT_ENUM 201
    #define CLIENT_SUPPR 202
    #define CLIENT_DEL 203
     
    typedef struct tt_client{
        int Valeur;
        struct tt_client *suivant;
        SOCKET Sock;            //Socket Client
    }t_client;
     
    int Client(int sc, t_client **p, int pa);

    devrait aller mieux.
    Si le probleme n est pas ca, il me faut plus de detail, probleme de compilation, d execution, conception ?

  3. #3
    Membre chevronné Avatar de jbarreau-mainson
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 446
    Par défaut
    Erreur remplacée.

    En fait mon programme se lance et se coupe direct.

    Process returned -1073741819 (0xC0000005) execution time : 0.344 s
    Press any key to continue.

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //Service ENUM pour Client.
    //Liste le nombre de clients
            case CLIENT_ENUM:
                pa = 0;
                while(p)
                {
                    pa++;
                    p = p->suivant;
                }
                printf("Il y a actuellement %d clients de connectés.\n", pa);
                break;
    on devrait avoir (*p) au lieu de p sauf erreur (mais le compilateur aurait dû te le signaler) .

  5. #5
    Membre chevronné Avatar de jbarreau-mainson
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    446
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 446
    Par défaut
    Oui j'avais également modifié ...

Discussions similaires

  1. Problème Socket Java architecture Serveur multi Client
    Par abdelhak_z dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 23/03/2015, 13h42
  2. Communication Serveur- Multi Client via socket
    Par jesuisperdu dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 14/03/2011, 09h37
  3. Probleme Serveur/Multi-client avec socket
    Par CouaC dans le forum Réseau
    Réponses: 9
    Dernier message: 18/06/2007, 00h49
  4. [sockets][UDP][C/C++] serveur multi-clients
    Par l@rry dans le forum Développement
    Réponses: 4
    Dernier message: 08/06/2006, 14h11
  5. Création d'un Serveur Multi Client
    Par N*E*R*D dans le forum Autres éditeurs
    Réponses: 5
    Dernier message: 16/03/2004, 17h13

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