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

Threads & Processus C++ Discussion :

création d'un serveur multi client (problème de thread)


Sujet :

Threads & Processus C++

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 7
    Points : 6
    Points
    6
    Par défaut création d'un serveur multi client (problème de thread)
    Bonjour,

    Je suis entrain de créer un serveur multi-client avec des threads...
    le problème apparaît lors de l'appel de ma fonction CreateThread
    #
    hProcessThread = CreateThread(NULL, 0,&server::ClientThread, &p,0,NULL);
    #
    et exactement dans le 3 éme paramètre parce ma fonction " ClientThread" doit retourner quelque chose ( je sais pas ce qu'elle doit retourner ) .

    voilà mon code :

    #
    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
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    server::server(int p)
    {
    	port = p;
    	//running         = false;
    }
     
     
    int server::init()
    {    
    	WORD wVersionRequested;
    	WSADATA	 Data;
    	int error= (WSAStartup(MAKEWORD(2,2), &Data ));
     
    	if(error != 0 )
    	{
    		cerr <<"WSAStartup a échoué "<< endl;
    		return 1;
    	}
    	else
    	{
    			ServerAddr.sin_family = AF_INET;
    			ServerAddr.sin_port = htons( port );   
    		//	ServerAddr.sin_addr.s_addr=inet_addr("192.168.241.174");	
    			ServerAddr.sin_addr.s_addr=htons(INADDR_ANY) ;	
    	}
     
    	cout <<"server correctement initialise" << endl;    
    	return 0;   
    }
     
    DWORD WINAPI server::ClientThread(void * p)
    {
     
    		struct thread_param *Obj = (struct thread_param      *) p ;
    	//coversion de p en objet de la structure thread_param 
    		server *s = Obj->ser;		 // mettre le contenu de ser dans *s
     
     
    		cout << "thread client demarre" << endl;
     
     
    	char buffer[100];
    			//**** envoi ****
     
    				strcpy(buffer, "coucou \n");
    				send(Obj->soc, buffer,strlen(buffer), 0);
    				cout<<"message envoye"<<endl;
     
    		int reponse = 0;	
    			do
    			{
    			//	cout<<"******** reception ...********"<<endl;
    				reponse = recv(Obj->soc, buffer, sizeof(buffer), 0);
    				cout<<"reponse"<<reponse<<endl;
    				buffer[reponse]='\0';
    				cout<<"msg recu "<<buffer<<endl;
     
    			}while(reponse=0);
     
     
    	return 0;
    }
     
    int server::start ()
    {
     
    	SOCKADDR_IN  			ClientAddr;
    	int          			ClientAddrLen;
    	HANDLE       			hProcessThread;
     
     
    	struct thread_param		p;
     
    		ListeningSocket = socket(AF_INET, SOCK_STREAM, 0);
     
    		if(ListeningSocket == INVALID_SOCKET)
    		{
    			perror("socket()");
    			exit(-1);
    		}
    			cout <<"socket correctement creee" << endl;  
    		if( bind( ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof( ServerAddr ) ) == SOCKET_ERROR )
    		{
    			cerr<<"bind a echoue avec l'erreur "<< WSAGetLastError()<< endl;
    			cerr<<"Le port est peut-être deja utilise par un autre processus "<< endl;
     
    			return 1;
    		} 
    			cerr<<"Bind... "<< endl;
    		if( listen( ListeningSocket, 5 ) == SOCKET_ERROR )
    		{
    	        cerr<<"listen a échoué avec l'erreur "<< WSAGetLastError()<< endl;
     
    			return 1;
    		} 
     
    		cout <<"serveur demarre : a l ecoute du port "<<port<< endl; 
    			running = true;
    			ClientAddrLen = sizeof( ClientAddr );
    		while(running)
    		{			
    	if(Newconnection = accept(ListeningSocket, (struct sockaddr *)&ClientAddr, &ClientAddrLen) == INVALID_SOCKET)
    		{
     
    	 cout<<"accept a echoue avec l erreur "<< WSAGetLastError() << endl;
     
    			return 1;
    		}
    			p.ser=this;
    			p.soc=Newconnection;
    			cout<<"client connecte..."<<endl;
    	hProcessThread = CreateThread(NULL, 0,&server::ClientThread, &p,0,NULL);
     
    		if ( hProcessThread == NULL )
    		{                       
    	cerr <<"CreateThread a échoué avec l'erreur "<<GetLastError()<< endl;
    		}
    	}
    	closesocket( ListeningSocket );
    	WSACleanup();
    	return 0;
    }
    #

    Merci d'avance

  2. #2
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Si tu ne sais pas ce que ta fonction doit retourner, alors on ne peut pas vraiment t'aider

    C'est toi qui choisi. Si tu n'en a rien à faire de la valeur de retour, renvoie 0. Si tu penses qu'un code de sortie peut être intéressant, alors n'hésite pas à renvoyer une valeur qui représente ton code de sortie. Tu peux ensuite récupérer cette valeur avec GetExitCodeThread()

    Sur un autre point, dans ta fonction ClientThread :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	do
    	{
    		...
    	} while(reponse=0);
    Ne vas pas boucler très longtemps... (et il ne sert à rien d'initialiser reponse avant d'entrer dans la boucle).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #3
    Membre émérite
    Inscrit en
    Avril 2010
    Messages
    1 495
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 1 495
    Points : 2 274
    Points
    2 274
    Par défaut
    Salut,

    Ben en fait sur le type de retour y'a pas le choix, puisqu’est utilisé l'api Windows CreateThread, il faut "obligatoirement" (hum ça sent le pléonasme) utiliser une fonction callback de "type threadProc" dont le prototype attendu est de la forme DWORD WINAPI ThreadProc(void* pParam), DWORD étant alors le type de retour.

    Par ailleurs, pour que le code puisse compiler (par rapport à ce point, j'ai pas regardé le reste), y'a deux solutions, soit placer la fonction callback en dehors de la class, soit l'y inclure comme étant static...

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 7
    Points : 6
    Points
    6
    Par défaut probléme principal resolu
    Bonjour,
    j'ai trouvé la solution:

    en fait la fonction CreateThread n'est pas une fonction membre de la classe Server, je n'aurai pas du mettre son prototype dans le fichier.h,

    Bref Merci pour l'aide
    et par rapport à la boucle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    do
    	{
    		...
    	} while(reponse=0);

    cette boucle sert à afficher tant que ya des caractere à afficher, Mais je vois qu'elle ne marche pas et le probleme est dans mon appel de RECV

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        char tabRecep[100];
    	do
    			{
    				cout<<"******** reception ...********"<<endl;
    				cout<<"reponse = "<<reponse<<endl;
    				reponse=recv(sock, tabRecep, sizeof(tabRecep), 0);
    				cout<<"reponse"<<reponse<<endl;
    				tabRecep[reponse]='\0';
    				cout<<"msg recu "<<tabRecep<<endl;
     
    			}while(reponse=0);
    le programme s’arrête à " recv(sock, tabRecep, sizeof(tabRecep), 0); "

    merci de m'aider à trouver le problème

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    socket bloquant, donc recv ne retournera que quand des données seront arrivées
    bonne chance

  6. #6
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Indépendamment de l'appel bloquant à recv, cette boucle ne va s'exécuter qu'une seule fois. La condition reponse=0 n'est pas écrite correctement. Etant donné que c'est une expression valide, elle n'est pas signalée comme erronée par le compilateur, mais elle signifie :

    * met 0 dans réponse
    * test réponse != 0

    Il faut réécrire la condition : reponse == 0 (et oui).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème Socket Java architecture Serveur multi Client
    Par abdelhak_z dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 23/03/2015, 13h42
  2. Problèmes application Client-Serveur multi-clients
    Par Shemsu-Hor dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 21/11/2011, 13h08
  3. Fork, pthread et serveur multi-clients
    Par Pico10 dans le forum POSIX
    Réponses: 13
    Dernier message: 05/01/2006, 11h48
  4. Serveur Multi-clients
    Par darsky dans le forum C++Builder
    Réponses: 5
    Dernier message: 16/04/2004, 09h53
  5. Création d'un Serveur Multi Client
    Par N*E*R*D dans le forum Autres éditeurs
    Réponses: 5
    Dernier message: 16/03/2004, 17h13

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