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:
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:
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:
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:
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:
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.