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

MFC Discussion :

Serveur multi-client CWinThread & CAsyncSocket


Sujet :

MFC

  1. #1
    Nouveau membre du Club
    Inscrit en
    Février 2009
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 7
    Par défaut Serveur multi-client CWinThread & CAsyncSocket
    Bonjour à tous,
    Je suis un débutant en C++ et en communication socket.
    Je souhaite réaliser un serveur capable de recevoir la connexion de plusieurs clients en utilisant les classes MFC !
    J'ai une classe CSocketService et CSocketServeur qui dérivent de CAsyncSocket, et d'après mes recherches pour créer un multi-client, on doit créer un thread après le Accpet() dans la méthode OnAccept() de CAsyncSocket.
    Mon thread est correctement crée, mais ensuite je ne sais pas quoi mettre comme code dans la fonction de mon thread pour qu'il puissent recevoir des messages des clients.
    Tous mon code est situé dans le fichier SocketServeur.cpp qui dérivent de CAsyncSocket
    Je déclare mon thread comme sa :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void CSocketServeur::OnAccept(int CodeErreur)
    {
    	Accept(m_SocService);
    /*********************************************************************************
    Initialisation Worker Thread 
    **********************************************************************************/
    	pthread = new CThread;
    	pthread = AfxBeginThread(WorkerRunFunction,0);
    /********************************************************************************/
    	CAsyncSocket::OnAccept(CodeErreur);	
    }
    La fonction de mon Worker Thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    /***************************************************************************
    Fonction thread de travail
    ***************************************************************************/
    UINT WorkerRunFunction (LPVOID pParam)
    {
    	//message de vérification du thread
    	AfxMessageBox("Thread correctement crée");
    	// ???? Code à déterminer
    	return 0;
    }
    Mon fichier SocketServeur.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class CSocketServeur : public CAsyncSocket
    {
    public:
    	CSocketServeur();
    	virtual ~CSocketServeur();
    	void OnAccept(int CodeErreur);
    	CSocketService m_SocService;
    	CWinThread *pthread;
    };
    Je vous remercie de votre aide d'avance

  2. #2
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    salut,
    tu n'as pas besoin de créer un thread pour la gestion du client.
    il que tu fasses une classe héritée de CAsyncSocket pour la partie client qui redéfinisse la méthode OnReceive.

  3. #3
    Nouveau membre du Club
    Inscrit en
    Février 2009
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 7
    Par défaut
    Merci pour ta réponse, mais je n'arrive pas à la comprendre, car mon serveur doit accepter plusieurs connexion de clients c'est là mon problème il en accepte seulement une et lorsque je lance un deuxième client il plante (erreur windows).
    La méthode OnReceive() est seulement utilisée chez le serveur pour lire les messages reçues du client connecté.
    Donc je ne vois pas pourquoi je doit redéfinir cette méthode chez le client.
    Il y a juste une message box qui s'affiche chez lui pour lui dire que la connexion a été réussie ou pas !
    Mon problème, enfin je pense est que je ne sais pas correctement utiliser utiliser les Thread ou les Socket.

    Pour résoudre mon pb je pense que je devrai appeler une méthode membre de CAsyncSocket dans mon thread et je ne sais pas comment faire ! Pouvez-vous m'aider ?

  4. #4
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    voir ce post:
    http://www.developpez.net/forums/d18...ation-serveur/
    ou encore ce post:
    http://www.developpez.net/forums/d94...socket-accept/
    l'objet client doit être autonome ,la socket serveur accepte la connexion crée la socket cliente .
    l'objet client doit dériver de CAsyncSocket ou de CSocket , le traitement de la réception des données se faisant dans la classe elle même.
    je le redit pas besoin de thread (voir explications dans les postes cités).
    voir aussi: http://msdn.microsoft.com/en-us/library/91c1cy99(VS.80).aspx

  5. #5
    Nouveau membre du Club
    Inscrit en
    Février 2009
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 7
    Par défaut
    Merci pour ta réponse je vai voir sa tout de suite !

  6. #6
    Nouveau membre du Club
    Inscrit en
    Février 2009
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 7
    Par défaut
    Ok donc si je comprend bien les autres post sur le forum.
    Pour chaque client qui souhaite se connecter, je doit faire en sorte que mon programme crée un nouveau Accept() avec la socket en paramètre, donc pas besoin de thread car tout est fait en interne, je doit juste m'occuper de coder correctement OnAccept() pour crée un objet de CAsynSocket à chaque fois qu'un client souhaite se connecter et l'associer au Accept().
    C'est bien sa ?
    Si sa marche comme sa les MFC c'est super sa simplifie la vie du développeur

  7. #7
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    oui c'est tout a fait ça ....
    tu peux aussi au moment au tu crées ta socket client lui passer un pointeur (a stocker en tant que donnée membre ) genre le document, la view etc ..
    celui-ci te permettra par exemple de lancer des traitements sur la réception de données avec des méthodes situées dans d'autres classes...

  8. #8
    Nouveau membre du Club
    Inscrit en
    Février 2009
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 7
    Par défaut
    Désolé de ne pas avoir répondu plus tôt mais je n'était pas disponible !!
    Maintenant que je pense avoir compris le problème du serveur multiclients sous MFC, je rencontre un autre problème . Je peu me connecter plusieurs fois à mon serveur (déco et reco) mais je ne peu pas en connecter plusieurs en même temps et recevoir des messages. Je pense que mon souci vient de ma méthode OnAccept, au niveau de la création de l'objet dynamique à lui passer en paramètre, et je ne vois pas comment faire.

    Si vous pouviez me guider pour trouver ce qui cloche je vous en remercie, voici mon code :
    méthode OnAccept() dans SocketServeur.cpp (classe qui dérive de CAsyncSocket)
    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
     
    void CSocketServeur::OnAccept(int CodeErreur)
    {
     
    	CSocketService * m_SocService = new CSocketService;
    	if(Accept(*m_SocService))
    	{
    		AfxMessageBox("Client connecté !!");
    	}
    	else
    	{
    		delete m_SocService;
    	}
     
    	CAsyncSocket::OnAccept(CodeErreur);
    }
    méthode OnReceive() dans SocketService.cpp(classe qui dérive de CAsyncSocket)
    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
     
    void CSocketService::OnReceive(int CodeErreur)
    {	TCHAR buffer[250];
    	CString m_strReception;
    	int nbRead = Receive(buffer,250);
    	buffer[nbRead] = 0;
    	CString taille(buffer);
    	m_strReception += taille; 
    	if (m_strReception == "quit")
    	{
    		ShutDown();
    		AfxMessageBox("client déco !");
    	}
    	else
    	{
    		AfxMessageBox(m_strReception);
    	}
    	CAsyncSocket::OnReceive(CodeErreur);
    }
    Où peut être que le problème viens de mon client, car le mien se connecte juste en faisant un : (projetDlg.cpp)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            socket = ipconfig.Create(SOCK_STREAM) ; //ipconfig objet de CSocketService qui dérive de CAsyncSocket
    	socket = ipconfig.Connect(m_ip, m_port);//passe en paramètre l'ip et le port
    et se déconnecte en faisant un close :
    Aidez moi svp ????

  9. #9
    Nouveau membre du Club
    Inscrit en
    Février 2009
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 7
    Par défaut
    Bonjour j'ai développé différemment mon client MFC qui utilise comme classe dérivée CAsyncSocket, car je pense que m'on problème viens d'ici. Sur appuie d'un bouton je fait appelle à la méthode OnConnect, pour qu'il puisse se connecter au serveur. Pas d'erreur de compilation mais là il m'affiche un message d'erreur de Windows me disant qu'il y à une erreur dans un fichier "sockore" ligne 644.

    Voici mon code "SocketService.cpp" qui dérive de CAsyncSocket :
    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
     
    void CSocketService::OnConnect(int CodeError)
    {
     
    /*********************
    Addresse du serveur
    *********************/
    	CString m_ip = "192.168.2.32";
    	UINT m_port = 5001;
    /*******************************
    Variables de la socket
    *******************************/
    	SOCKADDR sockaddr ;
    	int sockaddrlen ; 
    	int socket = -1;
    	sockaddrlen = sizeof(sockaddr);
    /**************************************
    Création socket et connexion au serveur
    **************************************/
    	socket = Create(SOCK_STREAM) ;	//création d'un socket un mode TCP
    	socket = Connect(m_ip, m_port);
    }
    Lorsque je fait ignoré sur le message d'erreur, le client envoie directement la valeur test que j'ai placée dans OnSend :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void CSocketService::OnSend(int CodeError)
    {
    	CString test="salut coco";
    	Send(test,strlen(test));
    	CAsyncSocket::OnSend(CodeError);
    }
    Sinon j'ai aussi entendu que mon problème pourrais venir de la mise en écoute de mon serveur car je fait dans mon projetDlg.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    BOOL Csocket_serveurv3Dlg::OnInitDialog()
    {
         .................
    // Création et mise en écoute
    m_Serveur.Create(5001);
    m_Serveur.Listen(); // permet par défaut la connexion de 5 clients ?
    }
    Voila donc je souhaiterai savoir si vous pouvez comprendre mon code d'où peut provenir le problème et d'avoir si possible plus d'information sur les fonctions membres de CAsyncSocket, merci pour votre aide.

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Peux-tu nous donner des détails sur l'assertion qui foire?

    Montre-nous la ligne 644 (et les lignes environnantes) de sockcore.cpp, dans les sources de MFC...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    salut,
    pense a tester les retours des méthodes comme Create ... et utiliser GetLasterror pour le numéro de l'erreur.
    sinon est tu sûr que que le port 5001 n'est pas utilisé ?

  12. #12
    Nouveau membre du Club
    Inscrit en
    Février 2009
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 7
    Par défaut
    C'est bon j'ai trouvé d'où viens mon problème !!!
    En faite le problème venez de mon client lors de la création de la socket .
    En faite pour la création de mon socket je faisais :
    Dans MonProjetDlg.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            socket = ipconfig.Create(SOCK_STREAM) ; 
    	socket = ipconfig.Connect(m_ip, m_port);
    En faisant cela, pour la fonction Create je lui mettait comme premier paramètre SOCK_STREAM qui à comme valeur 1, alors que sa valeur par défaut est 0 qui lui dit de chercher automatiquement un port libre, et son deuxième paramètre est par défaut en SOCK_STREAM (TCP).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    BOOL Create(
       UINT nSocketPort = 0,
       int nSocketType = SOCK_STREAM,
       long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE,
       LPCTSTR lpszSocketAddress = NULL 
    );
    Pour mon premier client sa fonctionnait mais lors de la création d'un deuxième la valeur du port était déjà prise et cela échoué.

    Donc j'ai simplement remplacer la ligne du Create par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	socket = ipconfig.Create(0,SOCK_STREAM) ;	
    	socket = ipconfig.Connect(m_ip, m_port);
    Et voila un serveur multi-client !!!!
    Encore merci pour votre aide

    Vous avez une zone sur le site ou on peut poster nos codes ?

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

Discussions similaires

  1. [sockets][UDP][C/C++] serveur multi-clients
    Par l@rry dans le forum Développement
    Réponses: 4
    Dernier message: 08/06/2006, 14h11
  2. serveur multi clients
    Par aaronw dans le forum C++Builder
    Réponses: 4
    Dernier message: 06/03/2006, 09h01
  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