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.