IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[CLASSE] Socket (Critiques, améliorations, questions)


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 21
    Par défaut [CLASSE] Socket (Critiques, améliorations, questions)
    Bonjour

    J'ai voulu aujourd'hui me faire une classe pour utiliser les sockets plus simplement. Je propose donc de la poster ici-même puis d'en parler après.

    -------------------------

    TKsocket.hh
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    #ifndef TK_SOCKET_HH
    #define TK_SOCKET_HH
     
    #include <string>
    #include <iostream>
     
    #ifdef WIN32
    #include <winsock.h>
    #pragma comment(lib, "ws2_32.lib")
    #else
    #include <sys/socket.h>
    #include <netdb.h>
    #endif
     
    #define TAILLE_BUFFEUR 255  //Taille du buffeur pour la fonction Read
     
    using namespace std;
     
    class TKsocket {
    private:
        struct sockaddr_in addr;
        int sok_ip4;
     
        static bool bInit;
        static unsigned int nbObj;
     
    public:
        TKsocket();
        ~TKsocket();
     
        /*////////////////////CONNECT/////////////////////////
        // Se connecter à un serveur.                       //
        // @Arguments : - hostname, nom de l'hote que l'on  //
        //      ------------veux rejoindre.                 //
        //              - port, le port auquel on dois se   //
        //      ------------se connecter.                   //
        // @Retourne : ?????                                //
        ////////////////////////////////////////////////////*/
        int Connect(string hostname, int port);
     
        /*/////////////////////WRITE//////////////////////////
        // Envoyer des données au serveur                   //
        // @Arguments : - message, le message à envoyer     //
        //      ------------au serveur                      //
        // @Retourne : ?????                                //
        ////////////////////////////////////////////////////*/
        int Write(string message);
     
        /*//////////////////////READ//////////////////////////
        // Lis les messages envoye par le serveur           //
        // @Arguments : Aucun                               //
        // @Retourne : Le message du serveur                //
        ////////////////////////////////////////////////////*/
        string Read();
    };
     
    #endif
    TKsocket.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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #include "TKsocket.hh"
     
    #include <string.h>
     
    bool TKsocket::bInit = false;
    unsigned int TKsocket::nbObj = 0;
     
    TKsocket::TKsocket() {
        ++nbObj;    //On ajoute cette objet au nombre d'objet déjà créé.
     
    #ifdef WIN32
     
        if(!bInit) {
            WSADATA WSAData;
            if(WSAStartup(MAKEWORD(2,0), &WSAData))
                exit(0);
            bInit = true;
        }
    #endif
     
        sok_ip4 = socket(AF_INET, SOCK_STREAM, 0); //TCP/IP
    }
     
    TKsocket::~TKsocket() {
        --nbObj;    //On suprime cet objet au nombre d'objet créé.
     
    #ifdef WIN32
     
        if(nbObj == 0) {
            closesocket(sok_ip4);
            WSACleanup();
            bInit = false;
        }
    #else
     
        close(sok_ip4);
    #endif
    }
     
    int TKsocket::Connect(string hostname, int port) {
        addr.sin_port = htons(port);  //Utilité de htons ?
                        //(Histoire de sens des données avec les sytèmes UNIX ...)
        addr.sin_family = AF_INET;    //TCP/IP
        addr.sin_addr = *((struct in_addr *)gethostbyname(hostname.c_str())->h_addr); //On récupère l'adresse numérique à partir du DNS
     
        return connect(sok_ip4, (struct sockaddr *) &addr, sizeof(addr));
    }
     
    int TKsocket::Write(string message) {
        return send(sok_ip4, message.c_str(), message.size(), 0); //A quoi correspond le 0 ?
    }
     
    string TKsocket::Read() {
        char buffer[TAILLE_BUFFEUR];
     
        int err = recv(sok_ip4, buffer, sizeof(buffer)-2, 0);
        if(err == -1)
            return "";
     
        buffer[err] = '\0';
     
        return buffer;
    }
    ------------------------
    Voila la classe en elle même. C'est un début, donc elle ne suporte que le TCP/IP et je ne fais pas de test d'erreurs

    Maintenant un main.cpp pour tester tout ça :
    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
    #include <iostream>
    #include <string>
     
    #include "TKsocket.hh"
     
    using namespace std;
     
    int main(int argc, char *argv[]) {
        string message(""), buffer("");
     
        TKsocket ircsok;
     
        ircsok.Connect("irc.fansub-irc.org", 6667);
     
        while(1) {
            /* LECTURE */
            buffer = "";
            buffer = ircsok.Read(); // On lis ce que le serveur veux nous dire
            if(buffer.size()) // On affiche seulement si il y a quelque chose
                cout << buffer;
     
            /* ECRITURE */
            message = "";
            getline(cin, message); // On recupere le message de l'utilisateur
            message += "\r\n";
            if(!strcmp(message.c_str(),"/quit\r\n")) // On quitte si message : /quit
                return 0;
            if(strcmp(message.c_str(),"\r\n")) // Si il y a un message on envois
                ircsok.Write(message);
        }
     
        return 0;
    }

    Alors là je test la classe sur un serveur irc. Et j'ai des petit problèmes bizarres. Enfin que je n'arrive pas à cerner

    Voila en sortie ce que ça peux donner :
    :Obelix.Fansub-IRC.org NOTICE AUTH :*** Looking up your hostname...
    :Obelix.Fansub-IRC.org NOTICE AUTH :*** Checking ident...
    NICK XXX
    :Obelix.Fansub-IRC.org NOTICE AUTH :*** Found your hostname
    5
    :Obelix.Fansub-IRC.org NOTICE AUTH :*** No ident response; username prefixed with ~
    PING :6B88D8A5
    ♠5NICK XXX
    Voila en rouge ce que je peux avoir comme méssages. J'ai cherché par rapport à la taille de mon char de réponse dans ma classe mais je n'ai pas trouvé.


    Donc pouvez vous critiquer cette classe (pour savoir ce que je devrais améliorer dans mes prochaines), proposer des améliorations et/ou m'aider dans le problème que j'ai ?


    Merci beaucoup,

  2. #2
    Membre expérimenté Avatar de lun4t1k
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    276
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 276
    Par défaut
    j'ai lu ça :
    if(recv(sok_ip4, buffer, sizeof(buffer)-2, 0)) //utilité du 0 ?
    C'est un flag que tu rajoutes, je l'ai toujours mis à 0
    Avec read, il n y'a a pas ce paramètre

    Et il ne faudrait pas finir ton buffer par \0 au lieu de \r\n ?
    (C'est une réellement une question )

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 21
    Par défaut
    Qu'elle rapidité

    En fais je finis mon message par \r\n parce que dans les sources de x-chat ils font comme ça :p
    Je vais tester avec le \0 pour voir

    Merci,

    edit : ça fais le même genre de soucis.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    433
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 433
    Par défaut
    Bonjour,

    Je ne me suis pas du tout renseigné quant aux fonctions concernant les sockets en C, mais pour dire vrai ta classe pourrait m'intéresser si jamais dans un projet j'avais à utiliser une communication avec un server.
    D'autant plus qu'elle est très simple d'utilisation !

    Alors quand la version finale sera fin prête, ca serait sympas de m'avertir ^^
    ++

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 21
    Par défaut
    Pas de problème je pense la faire évoluer ici
    Je posterais des mise à jour en fonctione de ce que l'on me conseille ou corrige

    edition de la classe :
    Oublie de #include <netdb.h> pour GNU/Linux.

    Sortie sous linux :

    trizolakai@localhost Socket % g++ -o TT TKsocket.o main.o
    trizolakai@localhost Socket % ./TT
    :Obelix.Fansub-IRC.org NOTICE AUTH :*** Looking up your hostname...
    :Obelix.Fansub-IRC.org NOTICE AUTH :*** Checking ident...
    3PNICK XXX
    :Obelix.Fansub-IRC.org NOTICE AUTH :*** Found your hostname
    ame...
    :Obelix.Fansub-IRC.org NOTICE AUTH :*** Checking ident...
    3PPASS
    :Obelix.Fansub-IRC.org NOTICE AUTH :*** No ident response; username prefixed with ~
    PING :1830CEFC
    TH :*** Checking ident...
    3PPASS
    :Obelix.Fansub-IRC.org 461 XXX PASS :Not enough parameters
    ername prefixed with ~
    PING :1830CEFC
    TH :*** Checking ident...
    3PNICK
    :Obelix.Fansub-IRC.org 461 XXX PASS :Not enough parameters
    ername prefixed with ~
    PING :1830CEFC
    TH :*** Checking ident...
    3P
    Toujours en rouge ce qui me semble mauvais. Je n'ai toujours pas trouvé :'(

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2007
    Messages : 21
    Par défaut
    J'avais oublié d'initialiser le char buffer[255];
    Merci steuf de me l'avoir fais remarquer.

    edition de la classe :
    Réécriture de la fonction Read() (Encore merci steuf ).
    Ajout d'une constante dans le headeur pour spécifier la taille du buffeur à la reception de données.

    Si vous avez des suggestions,

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Classe de connexion - Amélioration
    Par graphiks dans le forum Langage
    Réponses: 0
    Dernier message: 27/07/2010, 18h22
  2. erreur sur classe socket
    Par Gnius dans le forum Débuter
    Réponses: 5
    Dernier message: 29/11/2008, 13h56
  3. Probleme Class Socket
    Par autregalaxie dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 30/04/2007, 12h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo