begin process at 2010 03 14 01:43:43
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C++ & C++ .NET

 > 

Windows

 > 

Réseau & Internet

 > 

Communication serveur/client, dans les 2 sens, sans attente en UDP


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Communication serveur/client, dans les 2 sens, sans attente en UDP

mercredi 17 décembre 2008 à 17:12:01 | Communication serveur/client, dans les 2 sens, sans attente en UDP

mstarsup5

Bonjour à tous,

J'aimerais faire un programme C++ qui puisse établir une communication entre 2 ordinateurs (sous Windows) en utilisant winsock2, et en mode UDP.

Mon problème est que la communication doit se faire dans les 2 sens, de manière très rapide, et je ne peux donc pas bloquer le serveur ou le client en attente de réception de données.

J'ai donc cherché sur le net, et j'ai vu qu'il y avait plusieurs propositions:
 - utiliser des sockets non bloquantes
 - utiliser des threads
 - utiliser select.

N'ayant jamais utilisé ces solutions, je voulais vous demander d'après vous, quelle solution serait la plus adaptée à mon problème, et si vous connaissez des tutoriaux ou des exemples de codes que je pourrais étudier pour réaliser mon programme.

Merci infiniment à tous.

 Pourapprendretoujoursplus!
mercredi 17 décembre 2008 à 17:37:49 | Re : Communication serveur/client, dans les 2 sens, sans attente en UDP

mstarsup5

Remarque: je viens de lire que le point 3 ("select") était pour si il y avait plusieurs clients et prendre les données émises par un des clients quand elles arrivent. Ce n'est donc pas adapté à mon problème (un seul client, avec des émissions et des réceptions de données dans les 2 sens).

 Pourapprendretoujoursplus!
mercredi 17 décembre 2008 à 17:38:04 | Re : Communication serveur/client, dans les 2 sens, sans attente en UDP

fregolo52

Membre Club
Réponse acceptée !
Salut,

Bah euh ... Dans tous les cas tu es obligé de faire des threads.

Il y a plusieurs solutions plus ou moins viables surtout dans le cas multi clients.

Du côté client, tu crées un thread de réception avec socket bloquante, comme ca ton programme n'est pas bloqué.

Coté serveur 1 seul client :
Et du côté serveur tu crées un thread qui accepte la connexion du client et apres tu attends les données du client.

Coté serveur plusieurs clients:
Et du côté serveur tu crées un thread qui accepte la connexion des clients. Et tu crées un thread de réception par client.

Le select est pas mal aussi. Avec le select tu crées un seul thread pour la reception et l'acceptation de tous tes clients, c'est le gros avantage en multi client.

Des exemples ou tuto, tu en as à la pelle sur le Net. En regardant ici (en priorité  ), codeguru ou codeproject, tu ne peux trouver que ton bonheur.

Pour les sockets non bloquantes, je crois qu'il faut faire du pooling pour récupérer les données, donc c'est pas top.
mercredi 17 décembre 2008 à 18:01:02 | Re : Communication serveur/client, dans les 2 sens, sans attente en UDP

mstarsup5

Merci pour cette réponse fregolo52.

Pour le serveur et le client, il me faut donc 2 threads chacun? (un pour la réception, et un pour l'émission?)
Je laisse donc un thread (un sur le serveur, et un sur le client) en mode réception, socket bloquant, et l'autre thread (d'émission donc) dans une boucle?
mercredi 17 décembre 2008 à 18:38:08 | Re : Communication serveur/client, dans les 2 sens, sans attente en UDP

mstarsup5

Yop, j'ai avancé en attendant des réponses, j'arrive maintenant à créer et gérer plusieurs threads à la fois (dans un pgme), et l'UDP à sens unique (dans un autre programme)
Je merge les deux quand j'arrive chez moi, normalement ça devrait bien marcher en faisant un thread qui s'occupe de la réception de messages, et un thread qui s'occupe de l'envoi de données :)

Merci encore pour les réponses fregolo52 et tout le monde d'ailleurs :)

 Pourapprendretoujoursplus!
mercredi 17 décembre 2008 à 19:29:37 | Re : Communication serveur/client, dans les 2 sens, sans attente en UDP

fregolo52

Membre Club
Pas besoin de thread pour l'émission, ca peut etre dans le thread principal du programme. send ou sendto n'est généralement pas bloquant contrairement à recv
mercredi 17 décembre 2008 à 19:43:21 | Re : Communication serveur/client, dans les 2 sens, sans attente en UDP

mstarsup5

Réponse acceptée !
Oui, je comprends.

Je voyais le truc comme ça en fait:

[code]

//Code pour le 1er thread
DWORD WINAPI PremierThread ( LPVOID IpvThreadParam )
{
...
}


//Code pour le 2ème thread
DWORD WINAPI SecondThread ( LPVOID IpvThreadParam )
{
...
}


void main ( )
{

//TODO: si client, envoyer un message au serveur pour qu'il ait toutes les données nécesaires pour envoyer lui aussi des messages, et attendre une réponse ou réenvoyer un mesage. (Si pas de réponse au bout d'un certain temps, arrêter...)
//TODO: côté serveur du TOTO précédent.

//Séparation des tâches: réception/émission

HANDLE hThreads [ 2 ] ;
DWORD dwThreadId ;
DWORD dwThreadParam = 1 ;

// création des Threads

hThreads [ 0 ] = CreateThread ( NULL, NULL, PremierThread, &dwThreadParam, 0, &dwThreadId ) ;
hThreads [ 1 ] = CreateThread ( NULL, NULL, SecondThread, &dwThreadParam, 0, &dwThreadId ) ;

// attente de fin d'exécution des Threads (la thread principale attend la réponse des 2 threads créées donc)
WaitForMultipleObjects ( 2, hThreads, TRUE, INFINITE) ;

// destruction des Threads
CloseHandle ( hThreads [ 0 ] ) ;
CloseHandle ( hThreads [ 1 ] ) ;
}

[\code]

Sachant que c'est sur des machines tournant sur XP, j'utilise l'API windows.
Si pour c'est bête, ou autre, n'hésite pas à m'en faire part :)

 Pourapprendretoujoursplus!
mercredi 17 décembre 2008 à 20:27:05 | Re : Communication serveur/client, dans les 2 sens, sans attente en UDP

f_l_a_s_h_b_a_c_k

Réponse acceptée !
pour le serveur


/*************************************
Multi-threaded WebServer
**************************************/

#include <stdio.h>
#include <winsock.h>
#include <windows.h>

unsigned long webserv(unsigned fd) {
      int n;
      char *header="HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
      char data[512];
      char *sbuffer;
      char filename[256];
      long filesize;
      int bytes_read;
      FILE *f;
      n=recv(fd,data,512,0);              // recieve the request using fd
      data[n]=0;                          // NUL terminate it
      sscanf(data,"GET /%s ",filename);   // get the name of the file
      f=fopen(filename,"rb");             // open the file (might be binary)
      send(fd,header,strlen(header),0);   // send the header
                                          //
                                          // send the file
            if (f==NULL) {
                printf("File does not exit.\r\n");
                }
             else
              {
               // obtain file size.
               fseek (f,0,SEEK_END);    //indicate to end of file
               filesize = ftell (f);    //return the offset
               rewind (f);                    //redirect f to begining
              
               // allocate memory to contain the whole file.
               sbuffer = (char*) malloc (filesize);
            
               if (sbuffer == NULL)   printf("memory error.\r\n");
               else{
                      printf("Sending %s, size: %ld.\r\n",filename,filesize);
                      while (!feof(f)){
                                  if ( (bytes_read = fread (sbuffer,1,filesize,f)) > 0)
                                          send(fd,sbuffer,bytes_read,0);
                                  }//end of while
                      printf("Completed.\r\n");
                }//end of else
            
             free(sbuffer);
             fclose(f);
             } //end of else

closesocket(fd);
return 0;
}

int main (){
    int s;
    //n;
    unsigned SOCK;
   DWORD ThreadId;
   struct sockaddr sin={AF_INET,{31,144,0,0,0,0,0,0,0,0,0,0,0,0}};
   WSADATA wsaData;
   WSAStartup(MAKEWORD(1, 1), &wsaData);  // initialise windows sockets
   s=socket(PF_INET,SOCK_STREAM, 0);      // create a socket
   bind(s,&sin, sizeof(sin));             // bind it to port 80
   listen(s,10);                          // allow up to 10 incoming connections
    //HANDLE ThreadHandle;                         
   while(1) {
      SOCK=accept(s,NULL,NULL);                // wait for a request
       CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)webserv,(LPVOID)SOCK,0,&ThreadId);
      }
      /*ThreadHandle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)webserv,(LPVOID)SOCK,0,&ThreadId);
      if(ThreadHandle!=NULL){
        WaitForSingleObject(ThreadHandle,INFINITE);
        CloseHandle(ThreadHandle);     For single thread, second can start until first completed */
}


mercredi 17 décembre 2008 à 21:08:06 | Re : Communication serveur/client, dans les 2 sens, sans attente en UDP

mstarsup5

Merci flachback, mais le code que tu donnes correspond à un serveur qui envoie un fichier quand celui ci a été demandé par un client (et il gère plusieurs clients).
Le problème que j'avais est que le serveur peut agir comme un client (ie: envoyer des données quand bon lui chante, pas seulement quand un client lui fait une demande :) )

Je pense que je vais donc rester sur mon ti pseudo-code :)

Par contre, un énorme merci car ton code m'a permis de voir comment gérer plusieurs clients à la fois (je n'en ai pas l'utilité pour mon programme actuel mais ça me sera sûrement utile ;-)  ) et aussi l'envoi de fichiers (très utile :D)

Donc encore une fois merci infiniment pour toutes ces infos :)

 Pourapprendretoujoursplus!
samedi 20 décembre 2008 à 13:09:07 | Re : Communication serveur/client, dans les 2 sens, sans attente en UDP

katsankat

Membre Club
Salut, Depuis quand les threads sont obligatoires? Les programmeurs expérimentés les évitent car ils rendent le code complexe. Ils préfèrent le multiplexage d'entrées sorties asynchrone qui lui est miraculeusement portable à deux ou trois exceptions dans le FD_SET.


Cette discussion est classée dans : serveur, client, communication, attente, sens


Répondre à ce message

Sujets en rapport avec ce message

autoriser une communication client serveur en présence d'un firewall [ par Deserteagle38 ] j'ai un programme serveur qui doit communiquer avec un programme client à distance.Le problème c'est que le firewall bloque la communication provenant File de messages [ par samplaid ] Bonjour, Voici mon problème, j'ai plusieur client et un serveur. Chaque client se connecte a un canal de communication (avec la meme clé). Je passe u savoie si le Client est déconnecté [ par amoweb ] Salutje suis entrain de faire un serveur HTTP avec GCC ( sous windows).Le problème c'est que si le client se déconnecte pendant que j'envoie un fichie Meilleur moyen pour chat multi client. [ par deck_bsd ] Yop à tous,Voila , je suis en train de dévelloper un chat multi client pour le réseaux chez moi. Mais voila , en codant le serveur , je me trouve à un client serveur avec envoy successif de fichiers de même extention [ par salawi45 ] bonjour!j'ai parcouru plusieurs forums et à chaque fois on me parle de celui là, donc j'espère trouver ma réponse ici :-)je dévellope une application Soap et HTPPS [ par albanovisch ] Bonjour à tous, je voudrais réaliser une communication SOAP avec un serveur distant utilisant le https. Dans une communication simple via le protocle Aide client FTP [ par katson42 ] Bonjour à tous,dans le cadre d'un projet je dois réaliser un client FTP se connectant sur un serveur.J'ai réussi à créer la connexion avec le serveur boucle infinie et file de message [ par kyfranBibax ] Bonjour,j'ai un petit problème avec des files de messages et une boucle infinie.J'ai crée 2 programmes (un serveur et un cllient) qui communiquent via Serveur FTP utilisant le multithreading [ par ranzar ] Bonjour, Je suis entrain de développer une fonction sous C++ builder qui utilise un serveur FTP multithread: j'ouvre un serveur FTP sur ma machine et Socket Protocole HTTP [ par victorcoasne ] Bonjour,J'ai fait un proxy qui intègre un serveur WEB et lorsque que je lui demande de s'interroger, je me rends compte qu'il y a une erreur.Cette err


Nos sponsors


Appels d'offres

Sondage...

Comparez les prix

CalendriCode

Mars 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,296 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales