[Resolu]Serveur Multi Thread en C

Serveur Multi Thread en C [Resolu] - C - Programmation

Marsh Posté le 09-06-2009 à 11:50:06    

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
Reply

Marsh Posté le 09-06-2009 à 11:50:06   

Reply

Marsh Posté le 09-06-2009 à 12:05:18    

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.

Reply

Marsh Posté le 09-06-2009 à 12:06:57    

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).

Reply

Marsh Posté le 09-06-2009 à 12:12:51    

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
Reply

Marsh Posté le 11-06-2009 à 12:36:28    

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/
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed