Tim_reseau, classes pour reseau complet

Description

Cette source présente la librairie TIM_Reseau basée sur les sockets qui gèrent un réseau à haut niveau
(serveur et client multi-thread, protocoles TCP et UDP, template pour faciliter la gestion des
données, stockage des messages, gestions des clients etc...). Regarder Doc TIM_Reseau.txt pour plus d'informations.
La source est abondamment commentée.
Les deux projets client et serveur sont codés sous code::block compilés sous windows.
Je laisse le projet code::block pour ceux qui l'aurait.
Ces projets illustrent les classes TIM_server et TIM_client par l'exemple d'un chat
exploitant les 2 protocoles TCP et UDP ainsi que l'échange de structures de donnés
et la prise en charge du réseau en entier. Testez avec plusieurs clients connectés
pour voir les capacités et la simplicité de la classe.
Je n'ai jamais compilé sous Linux mais je ne pense pas que cela marche.

Source / Exemple :


/* Exemple de code utilisant TIM_Reseau coté serveur
   Auteur : Williamallas de Total_Immersion          */

#include <iostream>
#include "TIM_Reseau\TIM_Server.h"  // header de la classe TIM_Reseau

#define CLIENT_MAX 8
#define PORT_TCP 54000
#define PORT_UDP 54001
#define ID_TYPE_PROFILE 1 // c'est l'id du type contenant la structure Profile,
                          // l'id doit être le même pour le serveur et tous les clients
#define ID_TYPE_TEXT 2

struct Profile // structure contenant le profile d'un client
{
    char pseudo[25];
    int age;
};

struct Text  // structure contenent un message d'un client
{
    char txt[200];
    int protocole; // 1 = TCP, 2 = UDP
};

using namespace std;

/* Prototypes des fonctions */
void toutInit(TIM_Server & serveur);  // initialise le protocole TCP et UDP
void gestionMessage(TIM_Server & serveur, int id); // récupère et affiche les messages

int main()
{
    TIM_Server serveur;
    int err;

    toutInit(serveur); //  // initialise le protocole TCP et UDP

    serveur.createNewType(ID_TYPE_PROFILE, 50, sizeof(Profile));  // on crée un type pour les structures Profile
    serveur.createNewType(ID_TYPE_TEXT, 50, sizeof(Text));        // on crée un type pour les structures Text

    err = serveur.startListen(PORT_TCP);  // on écoute sur le port 54000 et on attend les connections
    if(err != OK){
        cout << "startListen() : " << serveur.printError(err) << endl;  // on affiche l'erreur
        system("pause");  exit(0);
    }
    err = serveur.startRecvUdp(PORT_UDP); // on écoute sur le port 54001 par le protocole UDP
    if(err != OK){
        cout << "startRecvUdp() : " << serveur.printError(err) << endl;  // on affiche l'erreur
        system("pause");  exit(0);
    }

    cout << "Lancemenet du serveur reussie !" << endl << endl;
    bool continu = true;
    int what, id;
    while(continu)   // la boucle d'attente des évenements
    {
        err = serveur.waitNewEvent(what, id, INFINITY); // on attend un évenement pendant un temps infinie
        if(err != OK)
        cout << serveur.printError(err) << endl;   // si une erreur s'est produite on l'affiche
        else                                       // sinon on traite l'évenement
        {
            Client_Info info; // servant à récupérer les informations d'un client
            switch(what)      // l'évenement est identifié par la variable what
            {
                case CONNECTION:  // un nouveau client s'est connecté
                serveur.getClientInfo(id, info);  // on demande les informations sur ce client, on utilise la structure Client_Info
                cout << "Le client d'id " << id << " s'est connecte." << endl;
                cout << "Informations : " << info.ip << ":" << info.port << endl; // on affiche les informations du client
                break;

                case DECONNECTION: // un client s'est déconnecté
                cout << "Le client d'id " << id << " s'est deconnecte." << endl;
                break;

                case MESSAGE:     // un nouveau message est arrivé, id contient l'id du type du message
                gestionMessage(serveur, id); // récupère et affiche les messages
                break;
            }
        }
        cout << endl;
    }
    return 0;
}

void toutInit(TIM_Server & serveur)
{
    if(serveur.init(CLIENT_MAX, true) == OK) // on initilise le module TCP en autorisant les échanges client-client
    cout << "Initialisation de TCP reussie" << endl;
    else{
        cout << "Erreur initialisation de TCP" << endl;
        system("pause");
        exit(0);
    }

    if(serveur.initUdp() == OK)    // on initilise le module UDP
    cout << "Initialisation de UDP reussie" << endl;
    else{
        cout << "Erreur initialisation de UDP" << endl;
        system("pause");
        exit(0);
    }
}

void gestionMessage(TIM_Server & serveur, int id) // récupère et affiche les messages
{
    int idClient, err;
    Profile profile;  // pour recevoir le profile des nouveaux clients
    Text txt;         // pour recevoir les messages de type Text
    if(id == ID_TYPE_PROFILE)  // si le message appartient au type Profile
    {
        err = serveur.recvRecentMessage(profile, id, &idClient); //on recupère  le message
        if(err == OK)  // si il n'y a pas d'erreur lors de la récupération du message
        {
            cout << "Profile du client d'id " << idClient << endl;
            cout << "Pseudo : " << profile.pseudo << "  Age : " << profile.age << endl; // on affiche le profile du client
        }
        else  // il y a une erreur
        {
            cout << "Impossible de recuperer le profile du client : " << serveur.printError(err) << endl;
        }
    }
    else if(id == ID_TYPE_TEXT)  // le message appartient au type Text
    {
        err = serveur.recvRecentMessage(txt, id, &idClient); //on recupère  le message
        if(err == OK) // si il n'y a pas d'erreur lors de la récupération du message
        {
            if(txt.protocole == 2) // le message est arrivé par la voie TCP
            cout << "Le client d'id " << idClient << " ecrit par UDP : " << txt.txt << endl;
            else                       // le message est arrivé par la voie UDP
            cout << "Le client d'id " << idClient << " ecrit par TCP : " << txt.txt << endl;
        }
        else // il y a une erreur
        {
            cout << "Impossible de recuperer le message du client : " << serveur.printError(err) << endl;
        }
    }
}

Conclusion :


Pour conclure, cette classe est utilisable dans presque toutes les situations, à
utiliser si vous ne voulez pas développer entièrement la partie réseau de votre
projet.
Si vous réussissez à adapter la librairie pour Linux vous pouvez m'envoyer le code
à l'adresse mentionnée à la fin de Doc TIM_Reseau.txt.
Si vous avez des questions n'hésitez pas.
Merci de me laisser vos commentaires et vos découvertes de bug.
Bon code !

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.