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

Langage C++ Discussion :

Ecriture Wrapper de Sokcet


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2010
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Août 2010
    Messages : 86
    Par défaut Ecriture Wrapper de Sokcet
    Bonjour,
    Je suis en train d'écrire un wrapper de socket de la libairie du C.
    Je me base sur le même modèle qu'en Java, c'est à dire :
    - Une classe pour une socket serveur nommé SocketWrapper
    - Une classe pour une socket client nommé SocketWrapperClient

    Mon problème est le suivant :
    Je voudrais pourvoir faire comme on le fait en Java, recevoire une socket cliente lors d'un accept d'un socket serveur.
    J'aimerais pouvoir écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SocketWrapperClient sockClient;
    sockClient=sockServ.sAccept();
    Et ainsi obtnenir un objet socket client maniulabre facilement.

    Dans SocketWrapperClient :
    J'ai pensé à écrire un constructeur qui permet de fabriquer un SocketWrapperClient à partir du descripteur de la socket, de la structure du contexte d'adressage de la socket, de la taille de ce contexte d'adressage.
    Puis à redéfinir l'opérateur d'affectation.
    Mais cette opération me parait un peu bancale et foireuse puisqu'elle m'oblige à recopier les structures de contexte d'adressages...

    Dans SocketWrapper :
    J'ai pensé à renvoyer un objet SocketWrapperClient à la sortie de la fonction sAccept().

    Ma solution est-elle viable ?
    Comment l'améliorer ?

    Voici le code mes 2 classes, écourté (je passe les include, typedef...)

    SocketWrapper.h :
    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
    class SocketWrapper
    {
        private:
            /*IP d'écoute de la socket serveur*/
            string ip;
     
            /*Port d'écoute du serveur*/
            unsigned short int port;
     
            /*Buffer pour la réception des requêtes*/
            char buffer[250]; //250 correspond à la taille du buffer
     
            /* Socket et contexte d'adressage du serveur*/
            SOCKADDR_IN sin;
            SOCKET sock;
            socklen_t recsize;
     
        public:
     
            /**Constructeur*/
            SocketWrapper(string ip, unsigned short int port) throw (ExceptionsTechnique);
     
            /**Fonction permettant d'accepter la connection d'un client
            Sortie : renvoit la socket du client qui vient de se connecter
            Post-Conditions : Le contexte d'adressage client est rempli */
            SocketWrapperClient sAccept() throw (ExceptionsTechnique);
     
    };
    SocketWrapper.cpp:
    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
    #include "SocketWrapper.h"
     
    SocketWrapper::SocketWrapper(string ip, unsigned short int port) throw (ExceptionsTechnique)
    {
        //Valorisation des attributs
        setIp(ip); //IP d'écoute
        setPort(port); //Port d'écoute
        this->recsize = sizeof(sin); //Pour la socket serveur
     
        //Création de la socket et valorisation du contexte d'adressage serveur
        if((this->sock=socket(AF_INET, SOCK_STREAM, 0))!=-1)
        {
            this->sin.sin_addr.s_addr = inet_addr(this->ip.data());  /* Adresse IP */
            this->sin.sin_family = AF_INET;                 /* Protocole familial (IP) */
            this->sin.sin_port = htons(this->port);               /* Listage du port */
            if(bind(this->sock, (SOCKADDR*)&this->sin, this->recsize)!=0)
            {
                throw ExceptionsTechnique("Le bind() de la la socket à échoué",1);
            }
        }
        else
        {
            throw ExceptionsTechnique("La création de la socket a echouée",1);
        }
    }
     
    SocketWrapperClient SocketWrapper::sAccept() throw (ExceptionsTechnique)
    {
        SOCKADDR_IN sinClient;
        SOCKET sockClient;
        socklen_t sizeClient = sizeof(sinClient);
     
        if((sockClient = accept(this->sock, (SOCKADDR*)&sinClient, &sizeClient)) !=-1)
        {
            return SocketWrapperClient(sockClient, sinClient, sizeClient);
        }
     
        else
        {
            throw ExceptionsTechnique("Erreur lors de la connection du client",1);
        }
    }
    SocketWrapperClient.h :
    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
    class SocketWrapperClient
    {
        private:
            /*IP sur laquelle on veut se connecter*/
            string ip;
     
            /*Port d'écoute du serveur sur lequel on veut se connecter*/
            unsigned short int port;
     
            /* Socket et contexte d'adressage de la socket */
            SOCKADDR_IN csin;
            SOCKET csock;
            socklen_t crecsize;
     
        public:
     
            /**Constructeur
            Avec specification de l'ip et du port du serveur à contacter
            */
            SocketWrapperClient(string ip, unsigned short int port) throw (ExceptionsTechnique);
     
            /**Constructeur full
            Il permet de construire une socket client en lui fournissant tous les paramètres :
            -Le descripteur de la socket
            -Le contexte d'adressage de la socket
            -La taille du contexte d'adressage de la socket*/
            SocketWrapperClient(SOCKET sock, SOCKADDR_IN sin, socklen_t size);
     
            /**Surcharge de l'opérateur d'affectation*/
            SocketWrapperClient operator=(const SocketWrapperClient& sockClient);
     
    };
     
    #endif // SOCKETWRAPPERCLIENT_H
    Et enfin :
    SocketWrapperClient.cpp :
    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
     
    SocketWrapperClient::SocketWrapperClient(string ip, unsigned short int port) throw (ExceptionsTechnique)
    {
        //Valorisation des attributs
        setIp(ip); //IP d'écoute
        setPort(port); //Port d'écoute
        this->crecsize = sizeof(this->csin); //Pour la socket
     
        //Création de la socket et valorisation du contexte d'adressage serveur
        if((this->csock=socket(AF_INET, SOCK_STREAM, 0))!=-1)
        {
            //Complétion du contexte d'adressage
            this->csin.sin_addr.s_addr = inet_addr(this->ip.data()); /* Adresse IP */
            this->csin.sin_family = AF_INET;                 /* Protocole familial (IP) */
            this->csin.sin_port = htons(this->port);               /* Listage du port */
     
            //Connection au serveur
            if(connect(this->csock, (SOCKADDR*)&this->csin, sizeof(this->csin)) == SOCKET_ERROR)
            {
                throw new ExceptionsTechnique("La connection à l'hôte distant a echouée",1);
            }
     
        }
        else
        {
            throw new ExceptionsTechnique("La création de la socket a echouée",1);
        }
    }
     
    SocketWrapperClient::SocketWrapperClient(SOCKET sock, SOCKADDR_IN sin, socklen_t size)
    {
        //On recopie ce qui est passé en argument dans nos paramètres
        this->csock=sock;
        this->csin=sin;
        this->crecsize=size;
    }
     
    SocketWrapperClient SocketWrapperClient::operator=(const SocketWrapperClient& sockClient)
    {
            this->csock=sockClient.getSock();
            this->csin=sockClient.getSin();
            this->crecsize=sockClient.getSize();
     
    }
    //L'implémentation de l'opérateur d'affectation me pose problème.


    Merci.
    Bonne soirée.

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    Peut-être que l'utilisation de l'idiome Pimpl pourrait t'aider ?

    MAT.

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2010
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Août 2010
    Messages : 86
    Par défaut
    Merci mais en en quoi l'utilisation de pimpl idome pourrait-elle m'aider ?

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Désolé c'était sans doute un peu succinct...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SocketWrapperClient sockClient;
    sockClient=sockServ.sAccept();
    Visiblement tu souhaites une sémantique de valeur pour tes SocketWrapperClient, ce qui va sans doute assez mal coller avec le fait qu'ils encapsulent une ressource système.
    Du coup pour transformer facilement une sémantique d'entité en sémantique de valeur à peu de frais on peut utiliser un Pimpl avec par exemple un boost::shared_ptr pour réaliser l'indirection.

    Bon ou sinon tu utilises Boost.Asio, et voilà !

    MAT.

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2010
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Août 2010
    Messages : 86
    Par défaut
    Avec boost.Asio, ça fonctionne comme j'aimerais ?
    Je pense que je vais essayer boost.Asio, ça sera sans doute plus robuste comme solution.
    Merci beaucoup et à bientôt !

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par Alpha573 Voir le message
    Avec boost.Asio, ça fonctionne comme j'aimerais ?
    Non vraisemblablement pas, mais jette un oeil, ça vaut le coup de s'y investir un peu !

    MAT.

Discussions similaires

  1. lecture/ecriture des broches RTS/CTS du port RS232
    Par .:: sly51 ::. dans le forum C
    Réponses: 3
    Dernier message: 24/10/2006, 15h28
  2. problem lors de l'ecriture d'un fichier
    Par gemai dans le forum C
    Réponses: 20
    Dernier message: 29/08/2003, 15h01
  3. Lecture et ecriture fichier .ini
    Par despe dans le forum C
    Réponses: 6
    Dernier message: 23/07/2003, 20h40
  4. Ecriture d'une procedure stockée XP
    Par WOLO Laurent dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/07/2003, 13h09
  5. Réponses: 13
    Dernier message: 14/06/2003, 22h15

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