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

C Discussion :

Sockets : Gerer plusieurs clients


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Petit dev
    Inscrit en
    Mars 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Petit dev

    Informations forums :
    Inscription : Mars 2017
    Messages : 6
    Par défaut Sockets : Gerer plusieurs clients
    Bonjour, j'ai crée grâce au socket un programme qui me permet de faire une discution entre un serveur et un client. C'était pas simple mais c'est fait (même si j'ai un petit bug au niveau du nettoyage de mes buffers)

    Mais la j'ai besoin de gerer la connexion de 2 clients et la possibilité de leurs répondre.
    Je cherche pas compliqué :
    • Le client 1 envoi un truc, je lui repond
    • Le client 2 m'envoi un truc, je lui repond


    Une discussion où c'est chacun son tour en gros.
    Ce n'est pas qu'une demande d'aide, c'est aussi pour savoir comment faire, je doit faire avec des fork et des processus pere/fils mais j'ai jamais rien fait de tel et faut que j'utilise ça ...

    Voici mon code (pour une discussion avec 1 client)

    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
     
    #include <stdio.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #define Internet_Port 2074
     
    // -------------------  Serveur : Envoi
     
    int main(int argc, char **argv){
        int sd_recu, lon, sr;
        struct sockaddr_in adsock, adacc;
        struct hostent *hptr;
        struct servent *sptr;
        char buffer_recu[100]="";
        char buffer_env[100]="Bye";
        char *prog;
        char *host;
        prog = argv[0];
     
        printf("\n____________\n SERVEUR \n------------\n\n ");
     
        // -------------------  Acquisition des infos Host
        host="localhost";
        if((hptr=gethostbyname(host))==NULL){
            perror("Probleme Info sur le host \n gethostbyname()");
            exit(1);
        }
     
        /* Initialiser le adsock avec les infos du host pour préparer adresse d'attachement */
        adsock.sin_family=AF_INET;
        adsock.sin_addr.s_addr=htonl(INADDR_ANY);
     
        // ------------------- récupération du numéro de port
        adsock.sin_port = htons(Internet_Port);
     
        // ------------------- création du socket
        if((sd_recu=socket(AF_INET,SOCK_STREAM,0))<0){
            perror("Erreur lors de la creation du socket \n socket()");
            close(sd_recu);
            exit(1);
        }
     
        if((bind(sd_recu,&adsock,sizeof(adsock)))<0){
            close(sd_recu);
            perror("Erreur lors du bind \n ");
            exit(1);
        }
     
        listen(sd_recu,5);
        lon = sizeof(adsock);
     
        if((sd_recu=accept(sd_recu,(char *)&adsock.sin_addr,&lon))<0){
            close(sd_recu);
            perror("Erreur accept \n accept()");
            exit(1);
        }
     
        // ------------------- boucle attente connexions
        while(strcmp(buffer_env,"STOP")){
            lon=sizeof(adsock);
     
            // ------------------- Reception de données
            if(recv(sd_recu,buffer_recu,sizeof(buffer_recu)-1,0)<0){
                perror("Erreur lors de la reception \n recv()");
                exit(1);
            }else{
                printf(" (Lui) <-- %s \n ",buffer_recu);
            }
            // ------------------- Envoi de données
            printf(" (Moi) --> ");
            fgets(buffer_env, sizeof(buffer_env), stdin);
            if((send(sd_recu,buffer_env,sizeof(buffer_env),0))<0){
                perror("Erreur lors de l'ecriture \n send()");
                exit(1);
            }
     
            for (int i=0; i>strlen(buffer_recu); i++){
                buffer_env[i]='\0';
                buffer_recu[i]='\0';
            }
     
     
        }
        // ------------------- Fin Programme
        close(sd_recu);
        exit(0);
    }
    Client.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
     
    #include <stdio.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #define Internet_Port 2074
     
    // -------------------  Client : Envoi et Reception
     
    int main(int argc, char **argv){
        int sd_env, n;
        struct sockaddr_in adsock; // Structure d'adresse du sock
        struct hostent *hostinfo; // Structure d'infos de l'host
        char buffer_env[9999]=""; // buffer_env pour les messages
        char buffer_recu[9999]="";
        char *host;
     
        printf("\n____________\n CLIENT \n------------\n\n ");
     
     
     
        // -------------------  Création du socket
        if((sd_env=socket(AF_INET, SOCK_STREAM, 0)) < 0){
            perror("Erreur creation socket ...");
            close(sd_env);
            exit(1);
        }
     
        // -------------------  Acquisition des infos Host
        host="localhost";
        if ((hostinfo=gethostbyname(host)) == NULL){
            perror("Host inconnu ...");
            exit(1);
        }
     
        // ------------------- Initialisation struct adsock avec infos de l'host, préparation de l'adresse d'attachement
        bcopy((char *)hostinfo->h_addr,(char *)&adsock.sin_addr.s_addr,hostinfo->h_length);
        adsock.sin_family = hostinfo->h_addrtype;
     
        // -------------------  On récupère le numéro de port
        adsock.sin_port=htons(Internet_Port);
     
        // -------------------  On va établir une connexion avec le serveur
        if(connect(sd_env, (struct sockaddr *)&adsock, sizeof(adsock)) < 0){
            perror("Probleme de connexion \n connect()");
            close(sd_env);
            exit(1);
        }
        listen(sd_env,5);
        while(strcmp(buffer_env, "STOP")){
            // ------------------- Envoi de données
            printf(" (Moi) --> ");
            fgets(buffer_env, sizeof(buffer_env), stdin);
            if(send(sd_env, buffer_env, strlen(buffer_env), 0) < 0){
                perror("Erreur lors de l'envoi \n send()");
                exit(1);
            }
            // ------------------- Reception de données
            if(recv(sd_env, buffer_recu, sizeof buffer_recu - 1, 0) < 0){
                perror("Erreur lors de la reception \n recv()");
                exit(1);
            }else{
                printf(" (Lui) <-- %s \n ",buffer_recu);
            }
     
            for (int i=0; i>strlen(buffer_recu); i++){
                buffer_env[i]='\0';
                buffer_recu[i]='\0';
            }
     
        }
        // ------------------- Fin Programme
        close(sd_env);
        exit(0);
    }
    Merci d'avance pour votre aide à tous !

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 477
    Par défaut
    Bonjour et bienvenue,
    L'appel qu'il te faut est select().

    Tu peux jeter un œil à ce fil, également.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Petit dev
    Inscrit en
    Mars 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Petit dev

    Informations forums :
    Inscription : Mars 2017
    Messages : 6
    Par défaut
    Si j'ai bien compris ce que j'ai lu, le select me permet de gerer le passage d'un client à un autre ?
    Mais je comprend pas trop les paramètres qu'il prend ...

    Serait-ce select(n°client, socket, NULL, NULL, temps) ?

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 477
    Par défaut
    Bonjour,

    Citation Envoyé par Hamtar0 Voir le message
    Si j'ai bien compris ce que j'ai lu, le select me permet de gerer le passage d'un client à un autre ?
    Non, select() te permet de surveiller plusieurs descripteurs en même temps. Cet appel est bloquant tant que tous les descripteurs surveillés sont eux-mêmes bloquants dans les conditions spécifiées (en lecture, en écriture, autre…) et rend la main dès qu'au moins un des descripteurs devient non-bloquant. Cela te permet de gérer à la fois les sollicitations des différents clients et les nouvelles connexions entrantes.

    Pour cela, il te faut définir plusieurs « jeux de descripteurs » (fdset), un pour chaque condition, qui contienne tous les descripteurs à surveiller.

    Ces jeux d'ensemble se remplissent avec les macros FD_SET, FD_ZERO, etc. décrites dans la man page. C'est nécessaire parce qu'à chaque descripteur est associé plusieurs qui vont te permettre ensuite de savoir quels sont les descripteurs qui ont débloqué l'appel (car il peut y en avoir plusieurs en même temps).

    Mais je comprend pas trop les paramètres qu'il prend ...
    Serait-ce select(n°client, socket, NULL, NULL, temps) ?
    • Le premier paramètre est le numéro du plus grand descripteur (tous jeux confondus) + 1 (pour qu'il sache jusqu'où aller) ;
    • Les trois suivants sont des pointeurs vers chacun des trois ensembles, respectivement, ou NULL ;
    • Le dernier est un pointeur vers une structure timeval indiquant une valeur de timeout, c'est-à-dire un délai maximum au delà duquel l'appel rendra la main quoi qu'il se passe. NULL aussi si tu ne veux pas que cela arrive.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Petit dev
    Inscrit en
    Mars 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Petit dev

    Informations forums :
    Inscription : Mars 2017
    Messages : 6
    Par défaut
    Désolé ... mais je comprend pas du tout comment mettre en place le select dans mon code ...
    Tu n'aurait pas un exemple à me montrer ? Ou une autre discussion où la personne à résolu son problème ?

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 477

Discussions similaires

  1. un Tserversocket pour plusieurs clients socket?
    Par andyafrique dans le forum C++Builder
    Réponses: 2
    Dernier message: 05/10/2006, 21h02
  2. [NIO] envoie d'image à plusieurs client via socket
    Par robert_trudel dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 01/10/2006, 23h11
  3. Réponses: 72
    Dernier message: 05/12/2005, 10h45
  4. [Socket] Plusieurs socket pour un client
    Par meda dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 24/05/2005, 17h24
  5. comment gerer plusieurs connexions client/serveur
    Par naili dans le forum C++Builder
    Réponses: 3
    Dernier message: 14/08/2002, 16h58

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