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,