NewbieContest

Programmation => Langages compilés => Discussion démarrée par: neibb le 02 Août 2018 à 11:27:08



Titre: [Resolu] C++ Probleme de connexion irc
Posté par: neibb le 02 Août 2018 à 11:27:08
Bonjour,
Dans le cadre de mon developpement personnel en programmation j'ai fini par me relancer a l'attaque du C.

Pour ce programme, je souhaite juste pour l'instant initialiser une connexion a un serveur irc.
(Je me suis base sur un prog que j'avais fait en python pour lancer la connexion et rejoindre un canal, ainsi qu'un exemple tout bete de communication client/serveur en C trouve sur le net. Du coup je concois que ca peut etre un joli micmac,  pour moi ca a ete le cas en tous cas, mais petit a petit je m'en sors.  :lol:)

Code:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

// Gestion des erreurs
void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int main()
{
    int ircsock, port, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[2048];

    port = atoi("6697");
//    port = atoi("22222");


    printf("Tentative de connexion...\n");
    ircsock = socket(AF_INET, SOCK_STREAM, 0);
    if (ircsock < 0)
        error("ERROR opening socket");
    server = gethostbyname("chat.freenode.net");
//    server = gethostbyname("localhost");
    if (server == NULL)
        {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
        }

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr,
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(port);
    if (connect(ircsock,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
        error("ERROR connecting");
    printf("Connecte!\r\n");


// Une fois connecte, le bot doit s'identifier sur le serveur irc puis rejoint un canal.
    n = write(ircsock,"USER bot bot bot bot\r\n",24); //Identification du bot
    if (n < 0)
         error("ERROR writing to socket ID");
    n = write(ircsock,"NICK MonBot\r\n",15); //Assigne le nick du bot
    if (n < 0)
         error("ERROR writing to socket NICK");
    n = write(ircsock,"JOIN #canalTest\r\n",19); //Rejoind le canal
    if (n < 0)
         error("ERROR writing to socket JOIN");

// Et on attend un message du serveur.
    while(1)
    {
        bzero(buffer,2048);
        n = read(ircsock,buffer,2048);
        if (n < 0)
            error("ERROR reading from socket");
        printf("%s\n",buffer);
    }
    close(ircsock);
    return 0;
}

En gros,
- quand je compile, pas d'erreurs
- Je vois bien que le message transit en local via write() je suppose que c'est toujours le cas sur freenode car pas d'erreur ici lors de l'exe.
- le proggramme se ferme dans le while(1) avec un "ERROR reading from socket: Connection reset by peer.

Pour moi, le fait de faire une boucle infinie me permetait de rester dans ma connexion. A la rigueur un 'time out' car pas de ping pong, mais ca devrait passer?
Que me manque-t-il?

Si quelqu'un pouvait m'eclaircir de sa lumiere.
Merci! ;)


Titre: Re : C++ Probleme de connexion irc
Posté par: Stockage le 02 Août 2018 à 15:39:00
Après un bref coup d’œil, je crois que tu n'as pas implémenté la réponse au PING.


Titre: Re : C++ Probleme de connexion irc
Posté par: neibb le 02 Août 2018 à 22:01:08
Comment repondre au PING si je n'arrive pas a le recevoir?
Pour moi le PING se gere apres reception des donnees, et visiblement c'est ici que ca bloque.

Je n'ai pas eu le temps de creuser plus que ca, mais merci de ta reponse.


Titre: Re : C++ Probleme de connexion irc
Posté par: flob le 02 Août 2018 à 22:15:14
Salut,

Alors je sais pas si c'est lié à ton problème mais tes write ne sont pas bons ! En effet, tu as compté "\r\n" comme si ça faisait 4 caractères alors que ça n'en fait que 2 en réalité.


Titre: Re : C++ Probleme de connexion irc
Posté par: neibb le 03 Août 2018 à 14:18:11
Ah cool merci!

J'en profite d'ailleurs pour soulever un autre point, au debut j'ai essaye de construire mon write() comme ca :
Code:
    std::string id("USER bot bot bot bot\r\n");
    n = write(ircsock, id, strlen(id));
Ce qui posait un probleme de type.

Apres quelques recherches, j'ai fini par faire comme ca :
Code:
    sprintf (buffer, "USER %s\r\n", user);
    n = send (ircsock, buffer, strlen (buffer), 0);
    //n = write(ircsock, buffer, strlen(buffer)); //Identification du bot
    if (n < 0)
         error("ERROR writing to socket USER");
Du coup j'ai remplace par write() et read() par send() et recv(), quelle est la reelle difference entre les deux?


J'ai aussi ajoute le pong :
Code:
    while(1)
    {
        bzero(buffer,2048);
        n = recv(ircsock, buffer, BUFSIZ-1, 0);
        if (n < 0)
            error("ERROR reading from socket");
        //printf("%s\n",buffer);
        if (strstr(buffer, "PING :"))
            {
                rcvmsg = strstr(buffer, "PING :") + strlen("PING :");
                snprintf(msg, 256, "PONG :%s\n", rcvmsg);
                send(ircsock, msg, strlen(msg), 0);
            }
    }

EDIT DE LA FIN: ayant ecris ce message en meme temps que je programmais, j'ai fini par trouver mon probleme :
L'utilisation du port SSL. En changeant de port la communication a fini par passer!
Mais ce sera un probleme pour plus tard! (je pense que je trouverais bien, ca doit juste etre un message qu'envoie le client pour confirmer qu'il accepte le certif)

Bon, l'essentiel c'est que ca marche enfin et que j'ai fini par comprendre...
(Comme souvent, probleme assez stupide en fait, desole si j'encombre le forum de post inutiles...)
Mais pour ma defense, c'est en forgeant que l'on devient forgeron.   :lol:


En tous cas merci! ;)


Titre: Re : Re : C++ Probleme de connexion irc
Posté par: Ge0 le 03 Août 2018 à 20:35:55
Ah cool merci!

J'en profite d'ailleurs pour soulever un autre point, au debut j'ai essaye de construire mon write() comme ca :
Code:
    std::string id("USER bot bot bot bot\r\n");
    n = write(ircsock, id, strlen(id));
Ce qui posait un probleme de type.

Tu peux utiliser la méthode c_str() pour obtenir un const char *. Mais qui dit C++, dit cast intelligent (static_cast ?).

http://www.cplusplus.com/reference/string/string/c_str/

Essaie d'utiliser boost pour faire de la programmation réseau, tant qu'à utiliser C++. Ça déchire. :)


Titre: Re : [Resolu] C++ Probleme de connexion irc
Posté par: neibb le 04 Août 2018 à 10:07:00
Citation
Tu peux utiliser la méthode c_str() pour obtenir un const char *.

Oui, j'ai fini par tomber dessus a force de chercher. Mais c'est vrai que pour l'instant je galere un peu entre mes char, char*, const char, const char*, etc etc... A chaque fois que je veux reutiliser une donnee, je me retrouve face a ce probleme! Mais ca vient petit a petit. :)

Pour l'utilisation de boost, je l'ai vu passer dans mes recherches, mais je n'ai pas creuse plus que ca. Son utilisation a l'air vraiment large... Dans quel sens l'utiliser pour le reseau? (mis a part ca, il a l'air utile pour bien des choses.)


En tous cas merci pour ces reponses, etant encore bien debutant, c'est deja un bon coup de main!