Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
788 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [Resolu]Serveur Multi Thread en C

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Resolu]Serveur Multi Thread en C

n°1893120
thanks33
Posté le 09-06-2009 à 11:50:06  profilanswer
 

bonjour a tous est a toute,
 
Je cherche a développer un serveur Multi Thread en C sur les plateforme windows et unix.
 
Malheureusement je ne m'en sort pas.
 
J'aurai besoin de conseils avisé sur les librairie a utiliser, ainsi que exemple si sa existe.
 
Mon serveur doit se connecter a plusieurs clients simultanément, grâce a leur adresse IP.
 
 
ps: google ne pas beaucoup aidé dans mes recherches.
 
 
Cordialement


Message édité par thanks33 le 11-06-2009 à 11:21:29
mood
Publicité
Posté le 09-06-2009 à 11:50:06  profilanswer
 

n°1893130
Olivier51
Posté le 09-06-2009 à 12:05:18  profilanswer
 

Les mots cles pour ta recherche sont : "network programming c"
 
Un bon tutorial sur le sujet (qui t'introduira aux socket(), connect(), etc) te parlera en meme temps du multi-threads.

n°1893133
Olivier51
Posté le 09-06-2009 à 12:06:57  profilanswer
 

Au passage se sont les clients qui se connectent aux serveurs. Dans ton cas ce que tu appelles des clients sont en fait des serveurs qui attendent les requetes des clients (ton serveur).

n°1893138
thanks33
Posté le 09-06-2009 à 12:12:51  profilanswer
 

merci de ton aide.
 
bonjour, voila se qui me bloque.
 
Je doit réalisé un outil de supervision de serveur Unix.
 
En réalité mon serveur tcp ip sera aussi un client, je m'explique :
 
le programme en C ou C++ devra être capable de recevoir un ordre grâce a un site internet, puis de lancer un ordre a chacun des client.
Puis un fois que la partie cliente a finie d'exécuter les script, il devra envoyer au serveur un fichier txt.
 

Code :
  1. [COLOR="Black"]function [/COLOR]envoi_serveur($envoi)  /* Permet l'envoie de la commande au serveur*/
  2. {
  3.   $port = 10000;  /*définition du port */
  4.   $adresse = "127.0.0.1"; /*définition de l'adresse ip du serveur */
  5.   $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);/* Cree une socket TCP/IP. */
  6.    if ($socket < 0)  /*Si le socket ne c'est pas créé */
  7.     {
  8.     echo "socket_create() a échoué : raison :  " . socket_strerror ($socket) . "<br />"; /*affiche l'erreur */
  9.     }
  10.    else /* Sinon*/
  11.     {
  12.      $resultat = socket_connect($socket, $adresse, $port); /* connexion au serveur*/
  13.      if ($resultat < 0) /*Si la connexion au serveur a échoué*/
  14.       {
  15.        echo "socket_connect() a échoué : raison : ($resultat) " . socket_strerror($resultat) . "<br />";/*affiche l'erreur */
  16.       }
  17.      else /* Sinon*/
  18.       {
  19.        socket_write($socket, $envoi, strlen($envoi)); /*envoi de la données*/
  20.       }
  21.     }
  22.   socket_close($socket); /*Fermeture du serveur*/
  23. }


 
qui envera un code qui ressemble a celui ci : 10XTOT-pprod
 
 
ma partie serveur ressemble a ceci
 

Code :
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <fstream>
  4. using namespace std;
  5. #include <winsock2.h>
  6. int main(int argc, char *argv[])
  7. {
  8.     // Initialisation
  9.     WSADATA initialisation_win32;
  10.     int erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
  11.     if (erreur!=0)
  12.     {
  13.         cout << "Desole, je ne peux pas initialiser Winsock du a l'erreur : ";
  14.         cout << erreur << " " << WSAGetLastError() << "\n\n";
  15.         system("PAUSE" );
  16.         return -1;
  17.     }
  18.     else
  19.     {
  20.           cout << "WSAStartup  : OK\n";
  21.     }
  22.     // Création de la socket
  23.     SOCKET id_de_la_socket;
  24.     id_de_la_socket=socket(AF_INET,SOCK_STREAM,0);
  25.     if (id_de_la_socket==INVALID_SOCKET)
  26.     {
  27.         cout << "Desole, je ne peux pas creer la socket du a l'erreur : ";
  28.         cout << WSAGetLastError() << "\n\n";
  29.         system("PAUSE" );
  30.         return -1;
  31.     }
  32.     else
  33.     {
  34.           cout << "socket  : OK\n";
  35.     }
  36.     // Ouverture du port 47836
  37.     SOCKADDR_IN information_sur_la_source;
  38.     information_sur_la_source.sin_family=AF_INET;
  39.     information_sur_la_source.sin_addr.s_addr=INADDR_ANY;
  40.     information_sur_la_source.sin_port=htons(10000); // Le porte 47836 est écouté
  41.     erreur=bind(id_de_la_socket,(struct sockaddr*)&information_sur_la_source,
  42.     sizeof(information_sur_la_source));
  43.     if (erreur!=0)
  44.     {
  45.         cout << "Desole, je ne peux pas ecouter ce port : ";
  46.         cout << erreur << " " << WSAGetLastError() << "\n\n";
  47.         system("PAUSE" );
  48.         return -1;
  49.     }
  50.     else
  51.     {
  52.           cout << "bind  : OK\n";
  53.     }
  54.     //  Attend une demande de connection
  55.     do
  56.           erreur=listen(id_de_la_socket,1);
  57.     while(erreur!=0);
  58.     cout << "listen  : OK\n";
  59.     // On accepte la connexion
  60.     SOCKET id_de_la_nouvelle_socket;
  61.     int tempo=sizeof(information_sur_la_source);
  62.     id_de_la_nouvelle_socket=accept(id_de_la_socket,
  63.     (struct sockaddr*)&information_sur_la_source,&tempo);
  64.     if(id_de_la_nouvelle_socket==INVALID_SOCKET)
  65.     {
  66.         cout << "Desole, je ne peux pas accepter la session TCP du a l'erreur : ";
  67.         cout << WSAGetLastError() << "\n\n";
  68.         system("PAUSE" );
  69.         return -1;
  70.     }
  71.     else
  72.         cout << "accept  : OK\n";
  73.     char buffer[4096]; long buffer2;
  74.     // Reçois la taille du nom du fichier (4 octet ou 32 bits)
  75.     int nombre_de_caractere=recv(id_de_la_nouvelle_socket,(char*)&buffer2,4,0);
  76.     if (nombre_de_caractere==SOCKET_ERROR)
  77.     {
  78.         cout << "Erreur, je n'ai pas recu la taille du nom de fichier !\n\n";
  79.         system("PAUSE" );
  80.         return -1;
  81.     }
  82.     // Reçois le nom du fichier
  83.     char*nomdefichier=new char[buffer2+1];nomdefichier[0]=0;
  84.     for (int i=0;i<buffer2;i+=nombre_de_caractere)
  85.     {
  86.         nombre_de_caractere=recv(id_de_la_nouvelle_socket,buffer,(buffer2-i<4096)?buffer2-i:4096,0);
  87.         if (nombre_de_caractere==SOCKET_ERROR)
  88.         {
  89.             cout << "Erreur, je n'ai pas recu le nom du fichier !\n\n";
  90.             system("PAUSE" );
  91.             return -1;
  92.         }
  93.         else
  94.         {
  95.             for (int y=0;y<nombre_de_caractere;y++)
  96.             {
  97.                 nomdefichier[y+i]=buffer[y];
  98.                 nomdefichier[y+i+1]=0;
  99.             }
  100.         }
  101.     }
  102.     cout << "Nom du fichier a recevoir : " << nomdefichier << "\n";
  103.     ofstream fichiers(nomdefichier,ios::out|ios::binary);
  104.     if (!fichiers)
  105.     {
  106.         cout << "Erreur, impossible de créer le fichier !\n\n";
  107.         shutdown(id_de_la_socket,2);
  108.         closesocket(id_de_la_socket);
  109.         shutdown(id_de_la_nouvelle_socket,2);
  110.         closesocket(id_de_la_nouvelle_socket);
  111.         WSACleanup();
  112.         system("PAUSE" );
  113.         return -1;
  114.     }
  115.     // Reçois la taille du fichier (4 octet ou 32 bits)
  116.     nombre_de_caractere=recv(id_de_la_nouvelle_socket,(char*)&buffer2,4,0);
  117.     if (nombre_de_caractere==SOCKET_ERROR)
  118.     {
  119.         cout << "Erreur, je n'ai pas recu la taille du fichier !\n\n";
  120.         system("PAUSE" );
  121.         return -1;
  122.     }
  123.     cout << "Taille du fichier a recevoir : " << buffer2 << "\n";
  124.     // Reçois le fichier
  125.     for (int i=0;i<buffer2;i+=nombre_de_caractere)
  126.     {
  127.         nombre_de_caractere=recv(id_de_la_nouvelle_socket,buffer,
  128.         (buffer2-i<4096)?buffer2-i:4096// Si le nombre de donnée restant à reçevoir
  129.         // est plus petit que le buffer on indique ce nombre sinon la taille du buffer
  130.         ,0);
  131.         if (nombre_de_caractere==SOCKET_ERROR)
  132.         {
  133.             cout << "Erreur, je n'ai pas recu le fichier !\n\n";
  134.             system("PAUSE" );
  135.             return -1;
  136.         }
  137.         else
  138.         {
  139.             fichiers.write(buffer,nombre_de_caractere);
  140.         }
  141.     }
  142.     delete[]nomdefichier;
  143.     fichiers.close();
  144.     shutdown(id_de_la_socket,2);
  145.     closesocket(id_de_la_socket);
  146.     shutdown(id_de_la_nouvelle_socket,2);
  147.     closesocket(id_de_la_nouvelle_socket);
  148.     cout << "\nLe fichier a bien ete recu !\n\n";
  149.     system("PAUSE" );
  150.     return 0;
  151. }


 
mais malheureusement rien ne se passe.
pourtant, un client PHP reçoit bien le message alors que le client C++ ne reçoit rien.
 
Cordialement

Message cité 1 fois
Message édité par thanks33 le 09-06-2009 à 21:38:00
n°1894100
Emmanuel D​elahaye
C is a sharp tool
Posté le 11-06-2009 à 12:36:28  profilanswer
 

thanks33 a écrit :


ma partie serveur ressemble a ceci
 

Code :
  1. //  Attend une demande de connection
  2.     do
  3.           erreur=listen(id_de_la_socket,1);
  4.     while(erreur!=0);
  5.     cout << "listen  : OK\n";




On ne fait pas de boucle sur listen(). On fait une boucle sur accept() (qui est bloquante).
 
A lire de A à Z :  
 
http://www.bien-programmer.fr/reseaux.htm
 
BUG : pour accept(), il faut fournir un sin (csin : client sin)  différent de celui du serveur (ssin : server sin).
 
Ceci devrait mieux fonctionner :

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <winsock2.h>
  4. int main (void)
  5. {
  6.    int ret = EXIT_SUCCESS;
  7. /* Initialisation */
  8.    WSADATA initialisation_win32;
  9.    int erreur = WSAStartup (MAKEWORD (2, 2), &initialisation_win32);
  10.    if (erreur != 0)
  11.    {
  12.       printf
  13.          ("Desole, je ne peux pas initialiser Winsock du a l'erreur : %d %d\n",
  14.           erreur, WSAGetLastError ());
  15.       ret = EXIT_FAILURE;
  16.    }
  17.    else
  18.    {
  19. /* Création de la socket */
  20.       SOCKET ssock = socket (AF_INET, SOCK_STREAM, 0);
  21.       printf ("WSAStartup  : OK\n" );
  22.       if (ssock == INVALID_SOCKET)
  23.       {
  24.          printf
  25.             ("Desole, je ne peux pas creer la socket du a l'erreur : %d %d\n",
  26.              erreur, WSAGetLastError ());
  27.          ret = EXIT_FAILURE;
  28.       }
  29.       else
  30.       {
  31.          SOCKADDR_IN ssin;
  32.          printf ("socket  : OK\n" );
  33.          /* Ouverture du port */
  34.          ssin.sin_family = AF_INET;
  35.          ssin.sin_addr.s_addr = INADDR_ANY;
  36.          ssin.sin_port = htons (10000);
  37.          erreur = bind (ssock, (struct sockaddr *) &ssin, sizeof (ssin));
  38.          if (erreur != 0)
  39.          {
  40.             printf
  41.                ("Desole, je ne peux pas me lier a ce port : %d %d\n",
  42.                 erreur, WSAGetLastError ());
  43.             ret = EXIT_FAILURE;
  44.          }
  45.          else
  46.          {
  47.             printf ("bind  : OK\n" );
  48.             /* Le port est mis en ecoute */
  49.             erreur = listen (ssock, 1);
  50.             if (erreur == SOCKET_ERROR)
  51.             {
  52.                printf
  53.                   ("Desole, je ne peux pas ecouter ce port : %d %d\n",
  54.                    erreur, WSAGetLastError ());
  55.                ret = EXIT_FAILURE;
  56.             }
  57.             else
  58.             {
  59.                printf ("listen  : OK\n" );
  60.                /* En attente de connexion d'un client */
  61.                {
  62.                   SOCKADDR_IN csin;
  63.                   int tempo = sizeof (csin);
  64.                   SOCKET csock =
  65.                      accept (ssock, (struct sockaddr *) &csin, &tempo);
  66.                   if (csock == INVALID_SOCKET)
  67.                   {
  68.                      printf
  69.                         ("Desole, je ne peux pas accepter la session TCP du a l'erreur : %d %d\n",
  70.                          erreur, WSAGetLastError ());
  71.                      ret = EXIT_FAILURE;
  72.                   }
  73.                   else
  74.                   {
  75.                      char buffer[4096];
  76.                      long buffer2;
  77.                      /* Reçoit la longueur du nom du fichier (4 octet ou 32 bits) */
  78.                      int nombre_de_caractere;
  79.                      printf ("accept  : OK\n" );
  80.                      /* -ed- pas portable ! */
  81.                      nombre_de_caractere =
  82.                         recv (csock, (char *) &buffer2, 4, 0);
  83.                      if (nombre_de_caractere <= 0)
  84.                      {
  85.                         printf
  86.                            ("Erreur, je n'ai pas recu la longueur du nom de fichier ! \n\n" );
  87.                         ret = EXIT_FAILURE;
  88.                      }
  89.                      else
  90.                      {
  91.                         char *nomdefichier;
  92.                         printf ("la longueur du nom de fichier est %ld\n",
  93.                                 buffer2);
  94.                         /* Reçois le nom du fichier */
  95.                         nomdefichier = malloc (buffer2 + 1);
  96.                         if (nomdefichier != NULL)
  97.                         {
  98.                            /* -ed- Horriblement compliqué. Quel est le format des données ?
  99.                               Je recommande :
  100.                               (Codage des valeurs numériques :  MSB en tete)
  101.                               [Origine:longueur]
  102.                               [0:2]    LN : Longueur du nom de fichier (16-bit)
  103.                               [2:LN]   Nom de fichier (chaine de caracteres)
  104.                               [2+LN:4] LD : longueur des données (32-bit)
  105.                               [6+LN:LD]Donnees
  106.                             */
  107.                            nomdefichier[0] = 0;
  108.                            {
  109.                               int i;
  110.                               for (i = 0; i < buffer2;
  111.                                    i += nombre_de_caractere)
  112.                               {
  113.                                  nombre_de_caractere =
  114.                                     recv (csock, buffer,
  115.                                           (buffer2 - i <
  116.                                            4096) ? buffer2 - i : 4096, 0);
  117.                                  if (nombre_de_caractere == SOCKET_ERROR)
  118.                                  {
  119.                                     printf
  120.                                        ("Erreur, je n'ai pas recu le nom du fichier !\n\n" );
  121.                                     return EXIT_FAILURE;
  122.                                  }
  123.                                  else
  124.                                  {
  125.                                     int y;
  126.                                     for (y = 0; y < nombre_de_caractere; y++)
  127.                                     {
  128.                                        nomdefichier[y + i] = buffer[y];
  129.                                        nomdefichier[y + i + 1] = 0;
  130.                                     }
  131.                                  }
  132.                               }
  133.                            }
  134.                            printf ("Nom du fichier a recevoir : %s\n",
  135.                                    nomdefichier);
  136.                            {
  137.                               FILE *fichiers = fopen (nomdefichier, "rb" );
  138.                               if (fichiers == NULL)
  139.                               {
  140.                                  printf
  141.                                     ("Erreur, impossible de créer le fichier !\n\n" );
  142.                                  ret = EXIT_FAILURE;
  143.                               }
  144.                               else
  145.                               {
  146.                                  /* Reçois la taille du fichier (4 octet ou 32 bits) */
  147.                                  nombre_de_caractere =
  148.                                     recv (csock, (char *) &buffer2, 4, 0);
  149.                                  if (nombre_de_caractere <= 0)
  150.                                  {
  151.                                     printf
  152.                                        ("Erreur, je n'ai pas recu la taille du fichier !\n\n" );
  153.                                     return EXIT_FAILURE;
  154.                                  }
  155.                                  printf
  156.                                     ("Taille du fichier a recevoir : %ld\n",
  157.                                      buffer2);
  158.                                  /* Reçois le fichier */
  159.                                  {
  160.                                     int i;
  161.                                     for (i = 0; i < buffer2;
  162.                                          i += nombre_de_caractere)
  163.                                     {
  164.                                        /* Si le nombre de donnée restant à reçevoir */
  165.                                        nombre_de_caractere =
  166.                                           recv (csock, buffer,
  167.                                                 (buffer2 - i <
  168.                                                  4096) ? buffer2 - i : 4096
  169.                                                 /* est plus petit que le buffer on
  170.                                                    indique ce nombre sinon la taille
  171.                                                    du buffer */
  172.                                                 , 0);
  173.                                        if (nombre_de_caractere ==
  174.                                            SOCKET_ERROR)
  175.                                        {
  176.                                           printf
  177.                                              ("Erreur, je n'ai pas recu le fichier !\n\n" );
  178.                                           return EXIT_FAILURE;
  179.                                        }
  180.                                        else
  181.                                        {
  182.                                           fwrite (buffer, 1,
  183.                                                   nombre_de_caractere,
  184.                                                   fichiers);
  185.                                        }
  186.                                     }
  187.                                  }
  188.                                  fclose (fichiers);
  189.                               }
  190.                            }
  191.                            printf ("\nLe fichier a bien ete recu !\n\n" );
  192.                         }
  193.                         free (nomdefichier);
  194.                      }
  195.                      shutdown (csock, 2);
  196.                      closesocket (csock);
  197.                   }
  198.                }
  199.             }
  200.          }
  201.          shutdown (ssock, 2);
  202.          closesocket (ssock);
  203.       }
  204.       WSACleanup ();
  205.    }
  206.    return ret;
  207. }


Il faut quand même revoir le mécanisme de réception des données...


Message édité par Emmanuel Delahaye le 11-06-2009 à 13:47:27

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [Resolu]Serveur Multi Thread en C

 

Sujets relatifs
Lancer l'appli heure/zone horaire windows depuis C++[Résolu] Utilisation d'une application winform en réseau
[Résolu] XML UTF-8 > Java String decodageLangage C, Projet, Puissance 4 en langage C
[C] Fork et Pipevariable et thread safe
Erreur Nonetype sur une regexp pourtant reconnue [résolu][C] Image ne s'affiche pas correctement sur un LCD
[Resolu][ASP.NET] deployement sur serveur IIS / pb de bibliotheque 
Plus de sujets relatifs à : [Resolu]Serveur Multi Thread en C


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR