le c++ pour les nul
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
le c++ pour les nul

forum d'entraide pour les débutant en c++
 
AccueilAccueil  PortailPortail  RechercherRechercher  Dernières imagesDernières images  S'enregistrerS'enregistrer  ConnexionConnexion  
Le Deal du moment : -38%
Ecran PC gaming 23,8″ – ACER KG241Y P3bip ...
Voir le deal
99.99 €

 

 Classe winsock pour newbie

Aller en bas 
2 participants
AuteurMessage
IoNAce




Nombre de messages : 12
Date d'inscription : 05/01/2006

Classe winsock pour newbie Empty
MessageSujet: Classe winsock pour newbie   Classe winsock pour newbie EmptyVen 3 Fév à 8:28

Bon ben voila mon fameux code dont j'avais parler sur un autre topic. Il sagit d'une classe qui gere le reseau sous windows. Serveur/ Client sous TCP/UDP, j'ai essaye de la rendre la plus accessible possible. Si vous ne comprenez pas tout allez voir sur cppfrance.com (d"esole pour la pub), le texte y est colore et mieux presente (ben oui moi j'ai un peu de mal avec cette interface tout en vert ...dsl)
voial le code => n'hesitez pas, je viens regulierement ici ou sinon ionace@latriyade.com
P.S. : je precise a tout ceux qui aurait la mauvaise idee de me le demande par mail que je ne programme pas a la demande (je recois souvant des mails de tel ou tel personne desirant ce programme et voulant que je le fasse gratuitement .... a bon entendeur) par contre si c'est pour un coup de paluche je suis dispo et OK !

Code:
/****
 ______________________________
|                        |
|AUTEUR : IonAce (jean84)      |
|E-MAIL : ionace@latriyade.com |
|______________________________|

Cette classe permet d'initialiser une connexion en TCP ou en UDP, avec choix du
mode serveur ou du mode client. Elle permet egalement d'envoyer des donnees sur
le reseau et d'en recevoir quelque que soit le protocole utilise.

Rermeciement à X. & Cosmobob de cppfrance.com pour leurs conseils.

****/

// Include standard pour utiliser winsock
#include <winsock2.h>
// On lie la librairie de winsock
#pragma comment(lib, "ws2_32.lib")

// Creations de nouvelles donnees
typedef unsigned int U_INT;  // entier non-signe
typedef enum MODE_CONNEXION {TCP, UDP};  // pour facilite le choix entre tcp et udp lors de la creation de l'objet
typedef enum ERREURS {DISCONNECT, SENDFAILED, GETFAILED, OK, NOTDEFINE};  // pour faciliter la comprehension des erreurs reseaux
typedef enum TYPE_SERVICE {SERVER, CLIENT};  // pour faciliter le choix entre serveur et client lors de la creation de l'objet
typedef enum TYPE_CONNEXION {TCPCONNECT, UDPCONNECT}; 
/* TYPE_CONNEXION => Permet a la classe de savoir quelle protocole utilise lors de l'envoi/reception de message. */

class Reseau
{
   protected :   
     // fonctions d'initialisation TCP
      SOCKET initTcpServeur(U_INT port); 
      SOCKET initTcpClient(char *pip, U_INT port);
      // fonction d'initialisation UDP
      SOCKET initUdp(TYPE_SERVICE *pSerCli, char *ip, U_INT port);
      // variable recevant le handle de la connexion en cours
      SOCKET s;
      // structure SOCKADDR_IN
      SOCKADDR_IN sin;
      // variable indiquant l'etat des connexions
      bool initSocket;
      // variable indiquant le type de connexion
      TYPE_CONNEXION tpc;
   
    public :
      /* Si serCli vaut true, mode serveur active. Si serCli vaut false, mode client active.
      Si modeConnexion = true, connexion en TCP sinon connexion en UDP. */     
      Reseau(MODE_CONNEXION mc, TYPE_SERVICE serCli, char *ip, U_INT port );  // constructeur
      Reseau(Reseau& r);  // constructeur de copie
      ~Reseau();  // destructeur
 
      // Petie fonction permettant de verifier l'etat des connexions. */
      bool etatConnexion();
     
      // Fonctions envoyants et recevant des donnees sur le reseau
      ERREURS envoiBuf(char *pSBuff);
      ERREURS recevBuf(char *pRBuff, int sizeBuff);
};

/* Constructeur */
Reseau::Reseau(MODE_CONNEXION mc, TYPE_SERVICE serCli, char *ip, U_INT port )
{
    initSocket = false;  // si aucune verif n'est bonne, initSocket reste aisni sur false
    if ( mc == TCP )  // connexion TCP
    {
        if ( serCli == SERVER )  // si l'utilisateur a choisie d'utiliser la fonction serveur
        {
            s = initTcpServeur(port);
            if ( s != INVALID_SOCKET ){  // si la connexion est valide
                initSocket = true;
               tpc = TCPCONNECT;  // on indique que le type de connexion est TCP
            }
        }
        else if ( serCli == CLIENT )  // si l'utilisateur a choisie d'utiliser la fonction client
        {
            s = initTcpClient(ip, port);  // recuperation du handle de la connexion
            if ( s != INVALID_SOCKET ){  // si la connexion est valide
                initSocket = true;
                 tpc = TCPCONNECT; 
             }
        }
    }
    else if ( mc == UDP )  // connexion UDP
    {
        s = initUdp(&serCli, ip, port);  // initialisation du protocole UDP et recuperation du HANDLE a travers s
        if ( s != INVALID_SOCKET )  // si s est valide (initialisation reussi)
        {
            initSocket = true;
            tpc = UDPCONNECT;  // on indique que le type de connexion est UDP
        }
    }
}

/* Constructeur de copie */
Reseau::Reseau(Reseau& r)
{
    SOCKET nS = r.s;  // copie de s
    SOCKADDR_IN nSin = r.sin; // copie se sin
    bool nInitSocket = r.initSocket;  // copie de initSocket
    TYPE_CONNEXION nTpc = r.tpc;  // copie de tpc (pas super utile mais au moins
                                  // tout le ponde dispose de son espace memoire
                                  // et y a pas d'ambiguite)
}

/* Destructeur */
Reseau::~Reseau()
{
   if ( initSocket )
   {
       closesocket(s);
       WSACleanup();
       initSocket = false;
    }
}

/* Fonctions membres privees */
SOCKET Reseau::initTcpServeur(U_INT port)
{
   // Initialisation des composants winsock
    WSAData wsa;
    WSAStartup(MAKEWORD(2,0), &wsa);
   
    // Creation d'une structure SOCKADDR_IN indispensable pour utiliser winsock
    SOCKADDR_IN cin;
   
    /* Declaration des variables de type socket utilise par le serveur. Ces variables
    representent le HANDLE de la connexion en cours.*/
    SOCKET s1;
    SOCKET s2; 
   
    // Remplissage de la structure SOCKADDR_IN
    sin.sin_addr.s_addr = INADDR_ANY;  // accepte n'importe quelle IP
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
   
    // Definition du socket
    s1 = socket(AF_INET,SOCK_STREAM,0);
   
   // Remplissage du socket
   bind(s1,(SOCKADDR*)&sin,sizeof(sin));
   
   // Mise en ecoute du serveur
    listen(s1,0);
   
    int sinsize;
   int err=0;
   
   sinsize=sizeof(cin);
   
   while (1)  // boucle infinie en attente d'une connexion sur s1
   {
      /* Si une connexion est realise sur le SOCKET s1, alors s2 prend le relai pour
       toute la suite de la communication et s1 se remet en ecoute.*/
       s2 = accept(s1, (SOCKADDR*)&cin, &sinsize);
      if ( s2 == INVALID_SOCKET )
          return INVALID_SOCKET;  // Erreur renvoye
        return s2;
           
    }
}

SOCKET Reseau::initTcpClient(char *pip, U_INT port)
{
   /* Pour toutes les declarations, voir iniTcpServeur(). C'est quasiment identique
    sauf que l'on n'utilise qu'une srtucture SOCKADDR_IN et qu'une variable de type SOCKET.*/ 
    WSAData wsa;
    WSAStartup(MAKEWORD(2,0), &wsa);
   
    SOCKET s1;
   
    // inet_addr() convertie la chaine de caractere en adresse IP valide.
    sin.sin_addr.s_addr = inet_addr(pip);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
   
    s1=socket(AF_INET,SOCK_STREAM,0);
   
   bind(s1,(SOCKADDR*)&sin,sizeof(sin));
   
   /* La difference avec le serveur et que le client n'attend pas de connexion.
   Il essaye directement de se connecter et s'il echoue, il renvoie INVALID_SOCKET,
   au lieu de la connexion en cours, a travers s1. */
   int result = connect(s1, (SOCKADDR *)&sin, sizeof(sin));
   if ( result )
        return INVALID_SOCKET;
   return s1;
}

SOCKET Reseau::initUdp(TYPE_SERVICE *pSerCli, char *ip, U_INT port)
{
    WSAData wsa;
    WSAStartup(MAKEWORD(2,0), &wsa);
   
    SOCKET s1;
   
    sin.sin_family = AF_INET;
    // si mode serveur choisi
    if ( *pSerCli == SERVER ){ 
        sin.sin_addr.s_addr = INADDR_ANY; // instruction pour le serveur
    }
    // si mode client choisi
    else if ( *pSerCli == CLIENT ){ 
      sin.sin_addr.s_addr = inet_addr(ip);  // instruction pour le client
    }
   sin.sin_port=htons(port);
   
   s1 = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
   int result = bind(s1,(SOCKADDR*)&sin,sizeof(sin));
   if ( result )
        return INVALID_SOCKET;  // en cas d'erreur
   /* Contrairement au TCP, l'UDP ne se connecte jamais. C'est pourquoi il n'y a
   aucune methode pour se connecter dans cette fonction. Une fois cet appel effectue,
   l'utilisateur n'a plus qu' a se soucier des fonctions envoiBuf() et recvBuf()
   pour communiquer avec un autre pc. */
   return s1;
}
   
/* Fonctions membres publiques */ 
bool Reseau::etatConnexion()
{
    /* Si la connexion est etablie, initSocket vaut true. En cas d'erreur, elle
    vaudra false. */
    return initSocket;
}
     
ERREURS Reseau::envoiBuf(char *pSBuff)
{
    if ( initSocket )  // on verifie si la connexion a ete initialise
    {
        int accuseEnvoi;
        if ( tpc == TCPCONNECT )  // si protocole TCP utilise
        {
             accuseEnvoi = send(s, pSBuff, strlen(pSBuff), 0);
             if ( accuseEnvoi == SOCKET_ERROR )  // erreur socket
                return SENDFAILED;
            else if ( accuseEnvoi == 0 )  // connexion interrompue
                return DISCONNECT;
            else  // tout est ok
                return OK;
        }
        else if ( tpc == UDPCONNECT )  // si protocole UDP utilise
        {
            accuseEnvoi = sendto(s, pSBuff, strlen(pSBuff), 0, (SOCKADDR *)&sin, sizeof(sin));
            if ( accuseEnvoi == SOCKET_ERROR )  // erreur socket
                return SENDFAILED;
            else  // tout est ok
                return OK;
        }
     }
    return NOTDEFINE;  // si la connexion n'a pas ete initlialise
}

ERREURS Reseau::recevBuf(char *pRBuff, int sizeBuff)
{
   if ( initSocket )  // on verifie si la connexion a ete initialise
   {
       int accuseReception;
       if ( tpc == TCPCONNECT )  // si protocole TCP utilise
       {
           accuseReception = recv(s, pRBuff, (sizeBuff-1), 0);
          
           if ( accuseReception == SOCKET_ERROR ){  // erreur lors de la reception
                return GETFAILED;
            } else if ( accuseReception == 0 ){  // connexion interrompue
                return DISCONNECT;
            } else {
               pRBuff[accuseReception] = '\0';
              return OK;  // en cas de reussite, on renvoi OK
           }
       }
       else if ( tpc == UDPCONNECT )  // si protocole UDP utilise
        {
            int sinSize = sizeof(sin);
           accuseReception = recvfrom(s, pRBuff, (sizeBuff-1), 0, (SOCKADDR *)&sin, &sinSize);
          
            if ( accuseReception == SOCKET_ERROR ){
                return GETFAILED;
            } else if ( accuseReception == 0 ){
                return DISCONNECT;
            } else {
                pRBuff[accuseReception] = '\0';
               return OK;
            }
        }
   }
   return NOTDEFINE;  // si la connexion n'a pas ete initlialise
}

J'espere que sa pourra vous servir, je pense avoir suffisament commente le code ....
sur ce, @+ et bon code !!
Revenir en haut Aller en bas
cosmonul
Admin
cosmonul


Nombre de messages : 54
Date d'inscription : 22/11/2005

Classe winsock pour newbie Empty
MessageSujet: Re: Classe winsock pour newbie   Classe winsock pour newbie EmptyDim 12 Fév à 13:58

jolie Very Happy
bravo a toi jaime beaucoup ton code
je le comprend et je reviens te parler dans 3 ans e,viron
gj ionace Wink
Revenir en haut Aller en bas
https://debutantcpp.1fr1.net
 
Classe winsock pour newbie
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
le c++ pour les nul :: programmations :: codes sources-
Sauter vers:  
Ne ratez plus aucun deal !
Abonnez-vous pour recevoir par notification une sélection des meilleurs deals chaque jour.
IgnorerAutoriser