logo Homepage
Pages: [1]
  Imprimer  
Auteur Fil de discussion: [Resolu] C++ Probleme de connexion irc  (Lu 3816 fois)
neibb

Profil challenge

Classement : 418/48812

Membre Junior
**
Hors ligne Hors ligne
Messages: 50


Voir le profil WWW
« 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.  )

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!
« Dernière édition: 03 Août 2018 à 14:21:48 par neibb » Journalisée

neibb
Stockage
Administrateur

Profil challenge

Classement : 13/48812

Membre Complet
*****
Hors ligne Hors ligne
Messages: 156

"Tant qu'on ne choisit pas tout reste possible"


Voir le profil WWW
« #1 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.
Journalisée

Newbie Contest Staff :
Stockage
Statut :
Administrateur
Citation :
Attendez, il s'est reincarné en tricycle !
neibb

Profil challenge

Classement : 418/48812

Membre Junior
**
Hors ligne Hors ligne
Messages: 50


Voir le profil WWW
« #2 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.
Journalisée

neibb
flob
Administrateur

Profil challenge

Classement : 23/48812

Membre Junior
*****
Hors ligne Hors ligne
Messages: 52


Voir le profil
« #3 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é.
Journalisée

Newbie Contest Staff :
Flob
Statut :
Administrateur
Citation :
...
neibb

Profil challenge

Classement : 418/48812

Membre Junior
**
Hors ligne Hors ligne
Messages: 50


Voir le profil WWW
« #4 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.  


En tous cas merci!
Journalisée

neibb
Ge0

Profil challenge

Classement : 15/48812

Membre Senior
****
Hors ligne Hors ligne
Messages: 366


Voir le profil WWW
« #5 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.
Journalisée
neibb

Profil challenge

Classement : 418/48812

Membre Junior
**
Hors ligne Hors ligne
Messages: 50


Voir le profil WWW
« #6 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!
Journalisée

neibb
Pages: [1]
  Imprimer  
 
Aller à: