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 :

Application client serveur


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut Application client serveur
    Bonjour, je viens de terminer mes applications (une app client et une app serveur) Ca compile et fonctionne parfaitement (sauf preuve du contraire )

    J'aimerai avoir des commentaires sur le code, des choses à modifier dans le but de le rendre plus stable.

    J'aimerai aussi avoir des "idées" sous forme de pseudo code style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    si truc = 0
    boucle
    affiche("s");
    tant que x=1
    Dans le but de réaliser un petit logiciel de conversation par ip (client/serveur) et là je vois flou, c'est le brouillard.

    Je dois partir en cours, je vais réfléchir sur le chemin à la façon de mettre en oeuvre un tel programme (gestion des boucles...)

    code 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
    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
    /*
      Name: MySock
     Email: <a href="mailto:samyhocine@hotmail.fr">samyhocine_at_hotmail.fr</a>
     Website: <a href="http://www.samsoft.ift.fr" target="_blank">samsoft.ift.fr</a>
      Copyright: Gpl v2
      Author: Samy Hocine
      Date: 07/10/07 18:14
      Description: Partie serveur
    */
    #include <stdio.h>
    #include <stdlib.h>
    #ifdef __cplusplus
    #error Be sure you are using a C compiler
    #endif
    #if defined (WIN32)
    #include <winsock2.h>
    #elif defined (UNIX)
    /* Rien pour le moment */
    #else
    #error not defined for this platform
    #endif
    #define MY_PORT 234
    #define SUCCESS 0
    #define FAILURE -1
    int main(void)
    {
     #if defined (WIN32)
            WSADATA WSAData;
         int error = WSAStartup(MAKEWORD(2,0), &WSAData);
     #else
        int error = 0;
      #endif
     if(!error)
     {
      /* 
      Prototype : int socket(int domain, int type, int protocol);
      SOCK_STREAM c'est uniquement pour TCP/IP. Pour UDP/IP c'est SOCK_DGRAM
      On construit une socket
      */
      SOCKET mySocket = socket(AF_INET, SOCK_STREAM, 0);
      /* Si ma socket est valide */
      if(mySocket != INVALID_SOCKET)
      {
       SOCKADDR_IN sin;
       int sock_err;
       char txt[256] = "Bienvenue sur notre serveur\0";
       fprintf(stdout, "La socket %d est ouverte en mode TCP/IP\n", mySocket);
     
       /* Adresse ip automatique */
         sin.sin_addr.s_addr = htonl(INADDR_ANY);
         sin.sin_family = AF_INET;
         /* Ecoute d'un port */
         sin.sin_port = htons(MY_PORT);
       sock_err = bind(mySocket, (SOCKADDR *) &sin, sizeof sin); 
       if(sock_err != SOCKET_ERROR)
       {
        /* On commence le listage */
        sock_err = listen(mySocket, 5); 
        fprintf(stdout, "Listage du port %d ...\n", MY_PORT);
        if(sock_err != SOCKET_ERROR)
        {
         /*On attend que quelqu'un se connecte */
         fprintf(stdout, "Attente de connection sur le port %d ...\n", MY_PORT);
         SOCKADDR_IN newSin;
              int recsize = (int) sizeof newSin;
              SOCKET newSocket = accept (mySocket, (SOCKADDR *) &newSin, &recsize);
              if (newSocket != INVALID_SOCKET)
              {
          int rsltOfShutdown;
          fprintf (stdout, "Connection d'un client avec la socket %d de %s:%d\n", newSocket, inet_ntoa (newSin.sin_addr), htons (newSin.sin_port));
     
          sock_err = send(newSocket, txt, sizeof(txt), 0);
     
          if(sock_err != SOCKET_ERROR)
          {
           fprintf(stdout, "Le message [%s] est envoye'\n", txt);
          }
          else
          {
           fprintf(stdout, "Erreur lors de l'envoie du message\n");
          }
          rsltOfShutdown = shutdown(newSocket, 2);
     
          if(rsltOfShutdown != SUCCESS)
          { 
           fprintf(stdout, "Erreur lors de la fin de connection\n");
          }
          else
          {
                 fprintf (stdout, "Fermeture du client avec la socket %d\n", newSocket);
                 closesocket(newSocket);
           fprintf(stdout, "Fermeture du serveur");
          }
         }
         }
        }
      }
      else
      {
       fprintf(stderr, "Socket %d invalide", mySocket);
      }
     }
     
     #if defined (WIN32)
            WSACleanup();
      #endif
     getchar();  
      return EXIT_SUCCESS;
    }
    client

    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
     
    /*
      Name: ClientMySocket
     Email: <a href="mailto:samyhocine@hotmail.fr">samyhocine_at_hotmail.fr</a>
     Website: <a href="http://www.samsoft.ift.fr" target="_blank">samsoft.ift.fr</a>
      Copyright: Gpl v2
      Author: Samy Hocine
      Date: 10/10/07 14:14
      Description: Partie client de MySock
    */
    #include <stdio.h>
    #include <stdlib.h>
    #ifdef __cplusplus
    #error Be sure you are using a C compiler
    #endif
    #if defined (WIN32)
    #include <winsock2.h>
    #elif
    /* Rien pour le moment */
    #else
    #error not defined for this platform
    #endif
    #define MYPORT 234
    int main(void)
    {
      #if defined (WIN32)
            WSADATA WSAData;
         int error = WSAStartup(MAKEWORD(2,0), &WSAData);
     #else
        int error = 0;
      #endif
     if(!error)
     {
      /* On construit la socket */
      SOCKET mySocket = socket(AF_INET, SOCK_STREAM, 0);
     
      if(mySocket != INVALID_SOCKET)
      {
       SOCKADDR_IN sin;
       sin.sin_addr.s_addr = inet_addr("127.0.0.1");
       sin.sin_family = AF_INET;
       sin.sin_port = htons(MYPORT);
       /* Si la connection est re'ussie */
       if(connect(mySocket, (SOCKADDR *) &sin, sizeof(sin)) != SOCKET_ERROR)
       {
        char txt[256] = "";
        fprintf(stdout, "Connection a %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
     
        if(recv(mySocket, txt, sizeof(txt), 0) != SOCKET_ERROR)
        {
         fprintf(stdout, "Message du serveur : %s\n", txt);
        }
        else
        {
         fprintf(stdout, "Erreur lors de la re'ce'ption du message");
        }
       }
       else
       {
        fprintf(stdout, "Erreur lors de la connection\n");
       }
       /* Fermeture de la socket */
       closesocket(mySocket);
      }
     }
     #if defined (WIN32)
            WSACleanup();
      #endif
      getchar();
      return EXIT_SUCCESS;
    }
    Merci d'avance

    PS: Je me suis basé principalement sur le cours réseau : http://emmanuel-delahaye.developpez.com/reseaux.htm (pour le fond)

  2. #2
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Indentation horrible.

    Le port < 1024, il faudra lancer ton appli en root sur Unix, c'est pas normal.

    En français on dit connexion et non connection

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char txt[256] = "Bienvenue sur notre serveur\0";
    Euh pourquoi tu mets un \0 à la main ? Ca le fait tout seul hein.

    J'aurais plutôt mis un truc dans ce genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char const * const txt = "Bienvenue sur notre serveur";
    Et pour envoyer n'utilise pas sizeof mais strlen comme c'est une chaine de caractères.

    Pas besoin du ""

    Et pour le recv il faut mettre sizeof(txt) - 1 histoire que si on t'en envoi plus ben tu n'ai pas de soucis.

    Normalement un truc comme ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int n = 0;
    if((n = recv(mySocket, txt, sizeof(txt) - 1, 0)) != SOCKET_ERROR)
    {
        txt[n] = 0;
        ...
    }
    Y'a d'autres petites erreurs de ce genre.

  3. #3
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut
    Attention a ne pas oublier le \0 final de ce que tu as recu.
    Aussi il est préférable de faire une boucle autour de recv tant que tu recois des données (qui te dis que tu ne recevra pas plus de 256 octets) et d'allouer dynamiquement la mémoire à ton buffer de sortie.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par |PaRa-BoL Voir le message
    Attention a ne pas oublier le \0 final de ce que tu as recu.
    Non, on ne reçoit pas de 0. Par contre, comme l'a fait remarqué Skyrunner, il faut prévoir une place en réception et le positionner correctement pour en faire une chaine C.

  5. #5
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut
    Non, on ne reçoit pas de 0.
    Oui c'est ce que j'ai dis "de ne pas oublier d'ajouter le \0 à ce qu'il a recu"

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par |PaRa-BoL Voir le message
    Oui c'est ce que j'ai dis "de ne pas oublier d'ajouter le \0 à ce qu'il a recu"
    Tu ne l'avais pas formulé comme ça, ce qui a rendu ton message incompréhensible...

  7. #7
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Merci pour ces commentaires, j'ai donc adapté mon code.

    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
    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
     
    /*
      Name: MySock
     Email: samyhocine_at_hotmail.fr
     Website: samsoft.ift.fr
      Copyright: Gpl v2
      Author: Samy Hocine
      Date: 07/10/07 18:14
      Description: Partie serveur
    */
    #include <stdio.h>
    #include <stdlib.h>
    #ifdef __cplusplus
    #error Be sure you are using a C compiler
    #endif
    #if defined (WIN32)
    #include <winsock2.h>
    #elif defined (LINUX)
    /* Rien pour le moment */
    #else
    #error not defined for this platform
    #endif
    #define MY_PORT 1025
    #define SUCCESS 0
    #define FAILURE -1
    int main(void)
    {
     #if defined (WIN32)
            WSADATA WSAData;
         int error = WSAStartup(MAKEWORD(2,0), &WSAData);
     #else
        int error = 0;
      #endif
     if(!error)
     {
      /* 
      Prototype : int socket(int domain, int type, int protocol);
      SOCK_STREAM c'est uniquement pour TCP/IP. Pour UDP/IP c'est SOCK_DGRAM
      On construit une socket
      */
      SOCKET mySocket = socket(AF_INET, SOCK_STREAM, 0);
      /* Si ma socket est valide */
      if(mySocket != INVALID_SOCKET)
      {
       SOCKADDR_IN sin;
       int sock_err;
       char txt[256] = "Bienvenue sur notre serveur";
       fprintf(stdout, "La socket %d est ouverte en mode TCP/IP\n", mySocket);
     
       /* Adresse ip automatique */
         sin.sin_addr.s_addr = htonl(INADDR_ANY);
         sin.sin_family = AF_INET;
         /* Ecoute d'un port */
         sin.sin_port = htons(MY_PORT);
       sock_err = bind(mySocket, (SOCKADDR *) &sin, sizeof sin); 
       if(sock_err != SOCKET_ERROR)
       {
        /* On commence le listage */
        sock_err = listen(mySocket, 5); 
        fprintf(stdout, "Listage du port %d ...\n", MY_PORT);
        if(sock_err != SOCKET_ERROR)
        {
         /* On attend que quelqu'un se connecte */
         fprintf(stdout, "Attente de connexion sur le port %d ...\n", MY_PORT);
         SOCKADDR_IN newSin;
              int recsize = (int) sizeof newSin;
              SOCKET newSocket = accept (mySocket, (SOCKADDR *) &newSin, &recsize);
              if (newSocket != INVALID_SOCKET)
              {
          int rsltOfShutdown;
          fprintf (stdout, "connexion d'un client avec la socket %d de %s:%d\n", newSocket, inet_ntoa (newSin.sin_addr), htons (newSin.sin_port));
     
          sock_err = send(newSocket, txt, strlen(txt), 0);
     
          if(sock_err != SOCKET_ERROR)
          {
           fprintf(stdout, "Le message est envoye'\n");
          }
          else
          {
           fprintf(stdout, "Erreur lors de l'envoie du message\n");
          }
          rsltOfShutdown = shutdown(newSocket, 2);
     
          if(rsltOfShutdown != SUCCESS)
          { 
           fprintf(stdout, "Erreur lors de la fin de connexion\n");
          }
          else
          {
                 fprintf (stdout, "Fermeture du client avec la socket %d\n", newSocket);
                 closesocket(newSocket);
           fprintf(stdout, "Fermeture du serveur");
          }
         }
         }
        }
      }
      else
      {
       fprintf(stderr, "Socket %d invalide", mySocket);
      }
     }
     
     #if defined (WIN32)
            WSACleanup();
      #endif
     getchar();  
      return EXIT_SUCCESS;
    }
    Client

    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
     
    /*
      Name: ClientMySocket
     Email: samyhocine_at_hotmail.fr
     Website: samsoft.ift.fr
      Copyright: Gpl v2
      Author: Samy Hocine
      Date: 10/10/07 14:14
      Description: Partie client de MySock
    */
    #include <stdio.h>
    #include <stdlib.h>
    #ifdef __cplusplus
    #error Be sure you are using a C compiler
    #endif
    #if defined (WIN32)
    #include <winsock2.h>
    #elif defiend (LINUX)
    /* Rien pour le moment */
    #else
    #error not defined for this platform
    #endif
    #define MYPORT 1025
    int main(void)
    {
      #if defined (WIN32)
            WSADATA WSAData;
         int error = WSAStartup(MAKEWORD(2,0), &WSAData);
     #else
        int error = 0;
      #endif
     if(!error)
     {
      /* On construit la socket */
      SOCKET mySocket = socket(AF_INET, SOCK_STREAM, 0);
     
      if(mySocket != INVALID_SOCKET)
      {
       SOCKADDR_IN sin;
       sin.sin_addr.s_addr = inet_addr("127.0.0.1");
       sin.sin_family = AF_INET;
       sin.sin_port = htons(MYPORT);
       /* Si la connection est re'ussie */
       if(connect(mySocket, (SOCKADDR *) &sin, sizeof(sin)) != SOCKET_ERROR)
       {
        char txt[256];
        fprintf(stdout, "connexion a %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
     
        if(recv(mySocket, txt, sizeof(txt), 0) != SOCKET_ERROR)
        {
         fprintf(stdout, "Message du serveur : %s\n", txt);
        }
        else
        {
         fprintf(stdout, "Erreur lors de la re'ce'ption du message");
        }
       }
       else
       {
        fprintf(stdout, "Erreur lors de la connexion\n");
       }
       /* Fermeture de la socket */
       closesocket(mySocket);
      }
     }
     #if defined (WIN32)
            WSACleanup();
      #endif
      getchar();
      return EXIT_SUCCESS;
    }
    Sinon EOL ne sert pas à grand chose vu que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char txt[256] = "mon texte\n";
    Fonctionne très bien (Enfin je sais pas si c'est correct après)

    J'ai aussi penser à un système d'interpreteur de commandes :

    com:>Fin
    /* Quitte et affice à l'autre qu'il est parti */
    com:>salut
    //Affiche salut car c'est pas répertorié comme une commande
    /* En gros */
    com:>truc
    /* Si truc est une commande alors effectuer une certaine action sinon afficher truc */
    Emmanuel (votre site ne fonctionne pas pour le moment )

    Pouvez vous m'expliquer un peu plus comment fonctionne le système :

    client <-> serveur <-> client2

    Avec un petit pseudo code (sans rentrer dans les détails) ou me passer un lien en français

    Merci d'avance

    PS: Le site refonctionne je regarde ca. Quel est le problème avec le port 234 (je l'ai pris au hasard sachant qu'il faut être en root sous linux pour utiliser le 23).

  8. #8
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Sous Linux pour ouvrir un port < 1024 il faut être en root, donc 243 < 1024...

    Revois ton indentation s'il te plait.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par _SamSoft_ Voir le message
    Merci pour ces commentaires, j'ai donc adapté mon code.

    Serveur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       char txt[256] = "Bienvenue sur notre serveur";
    Et la marque de fin de ligne ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        /* On commence le listage */
        sock_err = listen(mySocket, 5); 
        fprintf(stdout, "Listage du port %d ...\n", MY_PORT);
    Quel listage ? listen signifie 'écouter' en anglais. Il faut connaitre un minimum d'anglais pour pouvoir faire de la programmation.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          sock_err = send(newSocket, txt, strlen(txt), 0);
    OK
    Client

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        char txt[256];
     
        if(recv(mySocket, txt, sizeof(txt), 0) != SOCKET_ERROR)
    Tu es vraiment une tête de mule. On te dis qu'il faut placer le 0 final. C'est fait où ?
    Sinon EOL ne sert pas à grand chose vu que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char txt[256] = "mon texte\n";
    Fonctionne très bien
    Et alors ? J'ai jamais dit le contraire. Simplement ce type de terminaison est un choix possible parmi plusieurs. L'avantage d'utiliser l'abstraction EOL est qu'on peut changer de terminaison de ligne facilement.

    (En http, c'est pas '\n', si tu veux tout savoir...)

    J'ai aussi penser à un système d'interpréteur de commandes :
    OK.

    Pouvez vous m'expliquer un peu plus comment fonctionne le système :

    client <-> serveur <-> client2

    Avec un petit pseudo (sans rentrer dans les détails) ou me passer un lien en français
    Je crois que c'est le moment d'imaginer le scénario. Si tu ne réflechis jamais à un problème, tu ne vas pas avancer. Mets toi à la place de l'utilisateur et essaye d'imaginer ce qui se passe 'en coulisse'

    1 - quand tu ne connectes au serveur
    2 - quand l'autre client se connecte au serveur

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par _SamSoft_ Voir le message
    J'aimerai avoir des commentaires sur le code, des choses à modifier dans le but de le rendre plus stable.

    J'aimerai aussi avoir des "idées" sous forme de pseudo code style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    si truc = 0
    boucle
    affiche("s");
    tant que x=1
    Dans le but de réaliser un petit logiciel de conversation par ip (client/serveur) et là je vois flou, c'est le brouillard.

    Je dois partir en cours, je vais réfléchir sur le chemin à la façon de mettre en oeuvre un tel programme (gestion des boucles...)

    code serveur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     sock_err = send (newSocket, txt, sizeof (txt), 0);
    Non. On émet uniquement ce qui nous intéresse soit strlen(txt). Il n'y a aucune raison de transmettre des 0 quand on manipule du texte. Par contre,
    on transmet des lignes, c'est à dire du texte terminé par un marque de fin de ligne (CR, LF, CRLF etc. selon le protocole utilisé ou ses propres choix).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    /* EOL = CRLF */
    #define EOL "\r\n"
    <...>
             char txt[256] = "Bienvenue sur notre serveur"EOL;
    <...>
             sock_err = send (newSocket, txt, strlen (txt), 0);
    Merci de ne pas mentionner mon site si c'est pour écrire des horreurs pareilles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        char txt[256] = "";
    <...> 
        if(recv(mySocket, txt, sizeof(txt), 0) != SOCKET_ERROR)
    Ou alors, il faut que tu lises un peu mieux mes articles...

    http://emmanuel-delahaye.developpez....eaux.htm#texte

    Ensuite, pour un serveur mono-client, je conseille un interpréteur de commandes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
       socket := demarrer_serveur(PORT)
       client := attendre_client(socket)
       envoyer (client, "Hello")
       REPETER
          recevoir (client, commande)
          fin := interpreter (commande)
          IF NOT fin
             saisir (commande)
             emettre (client, commande)
          ENDIF
       JUSQU'A fin
       deconnecter (client)
       arreter_serveur (socket)
    Coté client, c'est tout simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
       socket := demarrer_client(IP, PORT)
       REPETER
          recevoir (socket, reponse)
          fin := interpreter (reponse)
          IF NOT fin
             saisir (commande)
             emettre (socket, commande)
          ENDIF
       JUSQU'A fin
       arreter_client (socket)
    Pour éviter tout blocage, on peut aussi séparer la commande de la réponse dans 2 threads différents :
    Emission
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
       REPETER
             saisir (commande)
             emettre (socket, commande)
       JUSQU'A fin
    Réception
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
       REPETER
          recevoir (socket, reponse)
          fin := interpreter (reponse)
       JUSQU'A fin
    'fin' étant partagé proprement entre les 2 taches.

    Nota les 2 fonctions 'interpreter' (celle du client et celle du serveur) constituent la partie 'applicative'. A chaque commande ou réponse reçue, un traitement particulier va être effectué. En gros, si un mot clé est reconnu, on fait une action particulière, sinon, on se contente d'afficher le message reçu.

    Cet exemple simpliste peut être réalisé pour vérifier la mise en en oeuvre du dialogue, la gestion des commandes etc.

    Dans la pratique, on ne fait pas comme ça. En effet, il n'y a aucun intérêt à mobiliser les capacité d'un serveur pour un seul client. On a donc une architecture construite comme ceci :

    Dialogue point à point

    client <---> serveur <---> client

    Les applications client sont identiques. Le serveur sert dans un premier temps à établir les connexions client/serveur (authentification, mise en attente de relation), puis à mettre en relation 2 clients à leur demande. (on est très proche d'un système téléphonique, sauf qu'il n'y a pas "d'appel". on est simplement 'en attente'.).

    Comme toujours, les détails de comportement et de protocole doivent être parfaitement spécifiés avant de se lancer dans l'analyse puis le codage.

    Nota : rien de tout ça n'a à voir avec le langage C.

Discussions similaires

  1. [Free Pascal] Application client/serveur en Pascal
    Par zouzou_zaza dans le forum Free Pascal
    Réponses: 15
    Dernier message: 02/09/2004, 17h57
  2. [Débutant] Application client serveur
    Par dk dans le forum Plateformes (Java EE, Jakarta EE, Spring) et Serveurs
    Réponses: 7
    Dernier message: 30/06/2004, 11h38
  3. Choix port pour application client-serveur
    Par Tiaps dans le forum Développement
    Réponses: 7
    Dernier message: 15/03/2004, 09h49
  4. Réponses: 2
    Dernier message: 01/10/2002, 12h25
  5. Langage le mieux adapté pour application client serveur ?
    Par guenus dans le forum Débats sur le développement - Le Best Of
    Réponses: 4
    Dernier message: 17/06/2002, 15h46

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