[C++] Bibliothèque pour les sockets

Fermé
Pico51 Messages postés 716 Date d'inscription mercredi 27 décembre 2006 Statut Membre Dernière intervention 16 juillet 2019 - 27 janv. 2010 à 16:33
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 1 févr. 2010 à 09:33
Bonjour,

Je suis à la recherche d'une bibliothèque permettant d'utiliser facilement les sockets. J'ai bien vu la bibliothèque "sys/socket.h" mais c'est du C et pas bien pratique.
J'ai cherché sur Internet pour voir ce qui existait mais je n'ai trouvé que des bibliothèques pas très fiable développé chacun dans son coin et qui ne propose pas une utilisation simple.
Ce que je veux faire, c'est un simple échange de données avec TCP entre un client et un serveur.

Connaissez-vous donc une bibliothèque permettant de faire ça facilement ?

Je vous remercie.

7 réponses

Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
1 févr. 2010 à 09:33
copie général de ce que j'ai fait.
déjà, le .h :
#ifndef __IOSOCKET__
#define __IOSOCKET__
#include <winsock2.h>
#define DBIOS 0
#define L_TR_RX 512
#define TCP 0
#define UDP 1
typedef short sock_t;
//------------------ class iosocket --------------------------------------------
class iosocket{
    public:
    iosocket(){connect=0;proto=0;};
    iosocket(const iosocket&);
    ~iosocket();
	//membres
    bool connect;// Etat logique de la connection
    bool proto; // type de protocole : TCP ou UDP(à faire)
    // donnees local
    SOCKET local;
    SOCKADDR_IN sinlocal;
    // donnees distantes
    SOCKET dist;
    SOCKADDR_IN sindist;
    // Fonctions membres
    virtual int init()=0;
    virtual int port()=0;
    virtual char* get_ip();
    inline virtual void open(unsigned int,char*,bool=0)=0;//{*this=iosocket(port,IP,proto);};
    virtual void close(){connect=false;/*closesocket(local);closesocket(dist);WSACleanup();*/}
    iosocket& operator=(const iosocket&);
    static const sock_t ends=1,endl=2; // manipulateurs
	bool connected()const;
	bool isTCP()const;
};
//-------------- Fin class iosocket --------------------------------------------
//----------------  Class Serveur ----------------------------------------------
struct serveur:public iosocket
{
    serveur(unsigned int,bool=0);
    serveur(unsigned int,char*,bool=0);
    int init();
    int port();
    inline void open(unsigned int port,char* IP=0,bool proto=0){*this=(IP==0)?serveur(port,proto):serveur(port,IP,proto);};
    //void close(){connect=false;closesocket(local);closesocket(dist);WSACleanup();}
};
//-------------------- Class Client --------------------------------------------
struct client:public iosocket
{
    client(char*,unsigned int,bool=0);
    client(){connect=false;};
    int init();
    int port();
    inline void open(unsigned int port,char* IP,bool proto=0){*this=client(IP,port,proto);};
    int set_dist(const char*,const int);
    //void close(){connect=false;closesocket(local);closesocket(dist);WSACleanup();}
};
//---------------- Declaration des fonctions de flux ---------------------------
#ifdef _CPP_STRING
#include <string>
iosocket& operator<<(iosocket& s,std::string c);
iosocket& operator>>(iosocket& s,std::string& c);
#endif
#ifndef STRICT_PORT
template<typename T>iosocket& operator>>(iosocket& s,T& i)
{
   if(!s.connect) {int t=s.init();if(t==0)s.connect=1;}
   recv(s.dist,(char*)&i,sizeof(T),0);
   return s;
}
template<typename T>iosocket& operator<<(iosocket& s,const T i)
{
    if(!s.connect) {int t=s.init();if(t==0)s.connect=1;}
    send(s.dist,(const char*)&i,sizeof(T),0);
    return s;
}
#else
iosocket& operator>>(iosocket& s,int& i);
iosocket& operator<<(iosocket& s,int i);
iosocket& operator>>(iosocket& s,double& i);
iosocket& operator<<(iosocket& s,double i);
#endif
iosocket& operator<<(iosocket& s,sock_t c);
iosocket& operator<<(iosocket& s,char const* c);
iosocket& operator>>(iosocket& s,char* c);

Le .cpp associé (donc à compiler avec ton projet) :
#include <stdlib.h>
#include "iosocket.h"
#include <string>
typedef short sock_t;
//---------------------- Implémementations -------------------------------------
iosocket& iosocket::operator=(const iosocket& a)
{
    closesocket(local);
    closesocket(dist);
    WSACleanup();
    connect=a.connect;
    local=a.local;
    dist=a.dist;
    sinlocal=sinlocal;
    sindist=sindist;
    return *this;
}
iosocket::iosocket(const iosocket& a)
{
    closesocket(local);
    closesocket(dist);
    WSACleanup();
    connect=a.connect;
    local=a.local;
    dist=a.dist;
    sinlocal=sinlocal;
    sindist=sindist;
 }
iosocket::~iosocket()
{
    closesocket(local);
    closesocket(dist);
    WSACleanup();
}
char* iosocket::get_ip()
    {
    if(!connect)return "non_connecter";
    return inet_ntoa(sindist.sin_addr);
    }
bool iosocket::connected()const{return connect;}
bool iosocket::isTCP() const{return !proto;}
serveur::serveur(unsigned int port,bool proto)
{
    connect=false;
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,0), &WSAData);
    local=socket(AF_INET,SOCK_STREAM,0);
    sinlocal.sin_family		= AF_INET;
    sinlocal.sin_addr.s_addr= htonl(INADDR_ANY);//inet_addr(c);
    sinlocal.sin_port		= htons(port);
    bind(local, (SOCKADDR *)&sinlocal, sizeof(SOCKADDR_IN));
    listen(local, 5);
}
serveur::serveur(unsigned int port,char*c,bool proto)
{
    connect=false;
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,0), &WSAData);
    local=socket(AF_INET,SOCK_STREAM,0);
    sinlocal.sin_family		= AF_INET;
    sinlocal.sin_addr.s_addr= inet_addr(c);
    sinlocal.sin_port		= htons(port);
    bind(local, (SOCKADDR *)&sinlocal, sizeof(SOCKADDR_IN));
    listen(local, 5);
}
client::client(char* c,unsigned int port,bool proto)
{
    connect=false;
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,0), &WSAData);
    local=socket(AF_INET,SOCK_STREAM,0);if(local==SOCKET_ERROR)printf("resu de local=socket : Socket error\n");
    sinlocal.sin_family		= AF_INET;
    sinlocal.sin_addr.s_addr	= htonl(INADDR_ANY);//inet_addr(c);
    dist=socket(AF_INET,SOCK_STREAM,0);if(dist==SOCKET_ERROR)printf("resu de dist=socket : Socket error\n");
    sindist.sin_family		= AF_INET;
    sindist.sin_addr.s_addr	= inet_addr(c);//htonl(INADDR_ANY);
    sindist.sin_port		= htons(port);
    //if(stt==SOCKET_ERROR) return -2;
}
int client::set_dist(const char *c,const int port)
{
    if (connect!=false) return -1;//empeche de modifier l'IP si connecter
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,0), &WSAData);
    local=socket(AF_INET,SOCK_STREAM,0);if(local==SOCKET_ERROR)printf("resu de local=socket : Socket error\n");
    sinlocal.sin_family		= AF_INET;
    sinlocal.sin_addr.s_addr	= htonl(INADDR_ANY);//inet_addr(c);
    dist=socket(AF_INET,SOCK_STREAM,0);if(dist==SOCKET_ERROR)printf("resu de dist=socket : Socket error\n");
    sindist.sin_family		= AF_INET;
    sindist.sin_addr.s_addr	= inet_addr(c);//htonl(INADDR_ANY);
    sindist.sin_port		= htons(port);
}
//------------------------- INIT !!! -------------------------------------------
int serveur::init()
{
    int leng=sizeof(SOCKADDR_IN); //necessaire, sinon, accept plante et n'attend pas la connection
    dist=accept(local, (SOCKADDR *)&sindist,&leng);
    if(dist!=SOCKET_ERROR) return 0;
    else return -1;
}
int client::init()
{
    int stt=bind(dist, (SOCKADDR *)&sindist, sizeof(SOCKADDR_IN));
    int tt=::connect(dist,(SOCKADDR *)&sindist, sizeof(sindist));
    if(tt!=SOCKET_ERROR) return 0;
    else return -1;
}
int client::port()
{
     if(!connect) return 0;
     return ntohs(sindist.sin_port);
}
int serveur::port()
{
     if(!connect) return 0;
     return ntohs(sinlocal.sin_port);
}
//------------------  Flux d'Entrées Sorties -----------------------------------
iosocket& operator<<(iosocket& s,const char* c)
{
    if(!s.connect) {int t=s.init();if(t==0)s.connect=1;else printf("pb dans init : %d\n",t);}
    for(int i=0;i<strlen(c)+1;i++)send(s.dist,&(c[i]),1,0);
    if(DBIOS)printf("envoi : %s $\n",c);
    char *ct=new char[5];
	recv(s.dist,ct,5,0);if(ct[0]!='O'||ct[1]!='K') printf("*!iosocket!* erreur, ct vaut : %s de lg %d et c vaut : %s\n",ct,strlen(ct),c);
	delete[] ct;
    return s;
}
iosocket& operator>>(iosocket& s,char* c)
   {
       if(!s.connect) {int t=s.init();if(t==0)s.connect=1;else printf("pb dans init : %d\n",t);}
       int i=0,rc;
       do{
         rc=recv(s.dist,&(c[i]),1,0);
		 if(rc!=1){s.connect=false;break;}
         i++;
         }
       while(c[i-1]!='\0'/*&&c[i-1]!='\n'*/);
       if(DBIOS)printf("recoi : %s $\n",c);
//       recv(s.dist,c,L_TR_RX,0);
       send(s.dist,"OK\r\n",5,0);
       return s;
   }
//#ifdef _CPP_STRING
iosocket& operator<<(iosocket& s,std::string c)
{
    if(!s.connect) {int t=s.init();if(t==0)s.connect=1;else printf("pb dans init : %d\n",t);}
	long n=c.size();
	send(s.dist,(char*)&n,sizeof(long),0);
	send(s.dist,c.c_str(),n*sizeof(char),0);
    /*char ct[4];
   if(c.size()<L_TR_RX)
    {
    send(s.dist,c.c_str(),c.size()+1,0);
    recv(s.dist,ct,3,0);if(ct[0]!='O'||ct[1]!='K') exit(1);
    return s;
    }
   else
    {
    std::string cc;
	int leng;
    for(int li=0;li<c.size()/L_TR_RX;li++)
    {
    cc=c.substr(li*L_TR_RX,L_TR_RX).c_str();
	leng=cc.size();
	if(leng<L_TR_RX)leng++;
    send(s.dist,cc.c_str(),leng,0);
    recv(s.dist,ct,3,0);if(ct[0]!='O'||ct[1]!='K') exit(1);
    }*/
    return s;
//    }
}
iosocket& operator>>(iosocket& s,std::string& c)
   {
       if(!s.connect) {int t=s.init();if(t==0)s.connect=1;else printf("pb dans init : %d\n",t);}
	   long n;
	   recv(s.dist,(char*)&n,sizeof(long),0);
	   char *cc=new char[n+1];cc[n]='\0';
	   recv(s.dist,cc,n*sizeof(char),0);
	   c=cc;
	   delete[] cc;
       /*char cc[L_TR_RX];
       recv(s.dist,cc,L_TR_RX,0);
       send(s.dist,"OK",3,0);
	   if(strlen(cc)<=L_TR_RX)return s;
       c=cc;
       while(1)
       if(c.find('\0')==std::string::npos)
              {
              recv(s.dist,cc,L_TR_RX,0);
              c+=cc;
              send(s.dist,"OK",3,0);
              }
       else break;*/
       return s;
   }
//#endif
iosocket& operator>>(iosocket& s,int& i)
   {
       char c[L_TR_RX];
       if(!s.connect) {int t=s.init();if(t==0)s.connect=1;}
#ifdef STRICT_PORT
       recv(s.dist,c,L_TR_RX,0);
       i=atoi(c);
#else
       recv(s.dist,(char*)&i,sizeof(int),0);
#endif
       return s;
   }
iosocket& operator<<(iosocket& s,int i)
{
    if(!s.connect) {int t=s.init();if(t==0)s.connect=1;}
#ifdef STRICT_PORT
    char *c=new char[L_TR_RX];
    itoa(i,c,10);
    send(s.dist,c,L_TR_RX,0);
    delete[] c;
#else
    send(s.dist,(char*)&i,sizeof(int),0);
#endif
    return s;
}
iosocket& operator>>(iosocket& s,double& i)
   {
       char c[L_TR_RX];
       if(!s.connect) {int t=s.init();if(t==0)s.connect=1;}
       recv(s.dist,c,L_TR_RX,0);
       i=atof(c);
       return s;
   }
iosocket& operator<<(iosocket& s,double i)
{
    if(!s.connect) {int t=s.init();if(t==0)s.connect=1;}
    char *c=new char[L_TR_RX];
    gcvt(i,12,c);
    send(s.dist,c,L_TR_RX,0);
    delete[] c;
    return s;
}
iosocket& operator<<(iosocket& s,sock_t c)
{
    if(c==iosocket::ends) s.close();
    if(!s.connect) {int t=s.init();if(t==0)s.connect=1;else printf("pb dans init/ends : %d\n",t);}
    if(c==iosocket::endl)
    {send(s.dist,"\r\n",3,0);
    char ct[4];recv(s.dist,ct,3,0);if(ct[0]!='O'||ct[1]!='K') exit(1);}
    return s;
}

Et le petit programme de test qui te permettra de comprendre comment ça fonctionne :
#include <string>
#include "iosocket.h"
int main(int argc,char ** argv)
{
	if(argc<2)return(1);
	if(std::string(argv[1])=="client")
	{
		client cl("127.0.0.1",123);
		printf("client\n\n");
		cl<<int(3);
		cl<<double(-6.3);
		std::string a("essai des string, avec une longueur inf a 512\r\n");
		cl<<a;
		a=("essai des string, avec une longueur sup a 512\r\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
		cl<<a;
		cl<<25l;
		cl<<(const char*)"essai\n";
		cl.close();
	}
	else
	{
		serveur sv(123);
		printf("\tServeur ! \n\n");fflush(stdout);
		int entier;
		sv>>entier;
		printf("entier (3) : %d\n",entier);
		double reel;
		sv>>reel;
		printf("reel (-6.3) : %e\n",reel);
		std::string a;
		sv>>a;
		printf("essai string court : %s\n",a.c_str());
		sv>>a;
		printf("essai string long : %s\n",a.c_str());
		long court;
		sv>>court;
		printf("essai template (25) : %d\n",court);
		char c[32];
		sv>>(char*)c;
		printf("%s\n",c);
		sv.close();
	}
	return 0;
}
	
	
C'est pour windows, sous Linux il y a quelques modifications à faire.
1
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
27 janv. 2010 à 16:58
J'ai fait un truc, mais c'est moyennement fiable.
L'idée c'est d'utiliser les sockets comme des flux :
serveur I;
I>>VAR;
en fait, I attend une connexion et met ce qu'il reçoit dans VAR.

client C(IP_serveur);
C<<VAR;

envoi la variable VAR au serveur après s'être connecté. L'inverse est bien entendu possible.
0
Pico51 Messages postés 716 Date d'inscription mercredi 27 décembre 2006 Statut Membre Dernière intervention 16 juillet 2019 69
27 janv. 2010 à 17:11
Euh ... j'ai pas tout suivi là !

Tu utilises quelle bibliothèque là ?
As-tu un code complet (ou presque) à me donner en exemple ?

Merci.
0
Pico51 Messages postés 716 Date d'inscription mercredi 27 décembre 2006 Statut Membre Dernière intervention 16 juillet 2019 69
30 janv. 2010 à 17:11
Up !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
1 févr. 2010 à 08:15
J'avais répondu en te mettant un lien, mais visiblement ça n'a pas marché.
0
Pico51 Messages postés 716 Date d'inscription mercredi 27 décembre 2006 Statut Membre Dernière intervention 16 juillet 2019 69
1 févr. 2010 à 08:47
Bah tu peux toujours me l'envoyer. Et si ça ne marche encore pas, enlève les points par des espaces.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
1 févr. 2010 à 09:26
https://celine-julien.pagesperso-orange.fr/julien/BigB/iosocket.h
sinon, je peux faire un copier coller ici.
0