Partage
  • Partager sur Facebook
  • Partager sur Twitter

Connexion d'un client à un serveur IRC (sockets)

    10 septembre 2017 à 17:12:20

    Bonjour,

    Je souhaite coder un client IRC qui se connecte à irc.hackerzvoice.net en utilisant les sockets. Cependant, je récolte toujours la même erreur, "registration timeout", après avoir envoyé les commandes et NICK et USER :

    Voici mon code :

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "root_me_1.h"
    
    
    int main()
    {
        // Si la plateforme est Windows
        #if defined (WIN32)
            WSADATA WSAData;
            WSAStartup(MAKEWORD(2,2), &WSAData); // sert à initialiser la bibliothèque WinSock
        #endif
    
        // socket et interface de connexion
        SOCKET sock;
        SOCKADDR_IN sin; // structure
    
        char buffer[TAILLE_MAX] = "";
        int nOctetsRecus = 0;
        int nOctetsEnvoyes = 0;
        int tailleBuffer = 0;
        int boucle = 1;
    
        // on crée une socket utilisant protocole TCP/IP
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if(sock == INVALID_SOCKET)
            printf("Erreur, socket non valide");
        printf("La socket %d est ouverte en TCP/IP.\n", sock);
    
        // on configure l'interface de connexion
        sin.sin_addr.s_addr = inet_addr("212.83.153.145"); // adresse IP du serveur IRC
        sin.sin_family = AF_INET;
        sin.sin_port = htons(PORT); // sin_port et sin_addr doivent être en Network Byte Order // htons() convertit un entier court depuis l'ordre des octets de l'hôte vers celuidu réseau (host to network short)
    
        if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) // si le client réussit à se connecter au serveur
            printf("Connexion a %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
        else
            printf("Erreur de connexion.");
    
    
        // on reçoit les données envoyées par le serveur
        nOctetsRecus = recv(sock, buffer, TAILLE_MAX, 0);
        if(nOctetsRecus != SOCKET_ERROR)
        {
            printf("%d octets ont ete recus\n", nOctetsRecus);
            printf("texte recu : %s", buffer);
        }
        else
            printf("Les donnees n'ont pas ete recues");
    
    
        // le client envoie des données au serveur
        sprintf(buffer, "NICK hoeplem\r\n");
        tailleBuffer = strlen(buffer)+1; // taille de la chaine + '\0'
    
        nOctetsEnvoyes = send(sock, buffer, tailleBuffer, 0);
        if(nOctetsEnvoyes != SOCKET_ERROR)
        {
            printf("%d octets envoyes au serveur\n", nOctetsEnvoyes);
            printf("texte envoye : %s", buffer);
        }
        else
            printf("Erreur : donnees non envoyees au serveur");
    
        // le client envoie des données au serveur
        sprintf(buffer, "USER hoeplem * * :hoeplem\r\n");
        tailleBuffer = strlen(buffer)+1; // taille de la chaine + '\0'
    
        nOctetsEnvoyes = send(sock, buffer, tailleBuffer, 0);
        if(nOctetsEnvoyes != SOCKET_ERROR)
        {
            printf("%d octets envoyes au serveur\n", nOctetsEnvoyes);
            printf("texte envoye : %s", buffer);
        }
        else
            printf("Erreur : donnees non envoyees au serveur");
    
    
        // on reçoit les données envoyées par le serveur
        nOctetsRecus = recv(sock, buffer, TAILLE_MAX, 0);
        if(nOctetsRecus != SOCKET_ERROR)
        {
            printf("%d octets ont ete recus\n", nOctetsRecus);
            printf("texte recu : %s", buffer);
        }
        else
            printf("Les donnees n'ont pas ete recues");
    
    
        // on ferme la connexion
        closesocket(sock);
    
    
        #if defined (WIN32)
            WSACleanup(); // libère les ressources allouées par la fonction WSAStartup()
        #endif
    
        getchar();
    
        return EXIT_SUCCESS;
    }
    

    Même après m'être documentée sur le protocole IRC (http://abcdrfc.free.fr/rfc-vf/rfc1459.html#41), je n'arrive pas à saisir ce qui cloche.

    Merci !

    Hoeplem

    EDIT :

    Le problème venait en fait de cette ligne :

    tailleBuffer = strlen(buffer)+1;
    Il suffisait de supprimer le +1 (le caractère \0 n'a pas à être envoyé au serveur).

    -
    Edité par Hoeplem 10 septembre 2017 à 18:10:01

    • Partager sur Facebook
    • Partager sur Twitter
    And those who were seen dancing were thought to be insane by those who could not hear the music.
      13 septembre 2017 à 12:42:28

      Je reviens vers vous pour l'étape suivante. Le client se connecte au serveur, qui lui envoie le message de bienvenue. J'ai édité le code en faisant une boucle.

      Si j'ai bien compris le protocole IRC, le serveur est censé envoyé un PING et le client doit lui renvoyer PONG.

      Mais voici ce qui se passe à la compilation : le serveur envoie le message de bienvenue, puis il y a environ 2 min de pause avant l'échange de PING/PONG.

      Pourquoi ce temps d'attente ?
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <math.h>
      #include "root_me_1.h"
      
      
      int main()
      {
          // Si la plateforme est Windows
          #if defined (WIN32)
              WSADATA WSAData;
              WSAStartup(MAKEWORD(2,2), &WSAData); // sert à initialiser la bibliothèque WinSock
          #endif
      
          // socket et interface de connexion
          SOCKET sock;
          SOCKADDR_IN sin; // structure
      
          double nombre1 = 0;
          double nombre2 = 0;
          double resultat = 0;
          char buffer[TAILLE_MAX] = "";
          int nOctetsRecus = 0;
          int nOctetsEnvoyes = 0;
          int tailleBuffer = 0;
          int boucle = 1;
      
          // on crée une socket utilisant protocole TCP/IP
          sock = socket(AF_INET, SOCK_STREAM, 0);
          if(sock == INVALID_SOCKET)
              printf("Erreur, socket non valide");
          printf("La socket %d est ouverte en TCP/IP.\n", sock);
      
          // on configure l'interface de connexion
          sin.sin_addr.s_addr = inet_addr("212.83.153.145"); // adresse IP du serveur IRC root-me
          //sin.sin_addr.s_addr = inet_addr("71.11.84.232"); // serveur chat.freenode.net
          sin.sin_family = AF_INET;
          sin.sin_port = htons(PORT); // sin_port et sin_addr doivent être en Network Byte Order // htons() convertit un entier court depuis l'ordre des octets de l'hôte vers celuidu réseau (host to network short)
      
          if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) // si le client réussit à se connecter au serveur
              printf("Connexion a %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
          else
              printf("Erreur de connexion.");
      
      
          // on reçoit les données envoyées par le serveur
          nOctetsRecus = recv(sock, buffer, TAILLE_MAX-1, 0); // will fail if TAILLE_MAX chars are read, the buffer is then not guaranteed NULL-terminated.
          if(nOctetsRecus != SOCKET_ERROR)
          {
              printf("%d octets ont ete recus\n", nOctetsRecus);
              printf("texte recu : %s", buffer);
          }
          else
              printf("Les donnees n'ont pas ete recues");
      
      
          // le client envoie des données au serveur
          sprintf(buffer, "NICK parallel\r\n");
          tailleBuffer = strlen(buffer);
          //tailleBuffer = sprintf(buffer, "NICK parallel\r\n");
      
          nOctetsEnvoyes = send(sock, buffer, tailleBuffer, 0);
          if(nOctetsEnvoyes != SOCKET_ERROR)
          {
              printf("%d octets envoyes au serveur\n", nOctetsEnvoyes);
              printf("texte envoye : %s", buffer);
          }
          else
              printf("Erreur : donnees non envoyees au serveur");
      
          // le client envoie des données au serveur
          sprintf(buffer, "USER parallel 0 * :parallel\r\n");
          tailleBuffer = strlen(buffer);//+1; // taille de la chaine + '\0' //tailleBuffer = sprintf(buffer, "USER parallel 0 * :parallel\r\n");
      
          nOctetsEnvoyes = send(sock, buffer, tailleBuffer, 0);
          if(nOctetsEnvoyes != SOCKET_ERROR)
          {
              printf("%d octets envoyes au serveur\n", nOctetsEnvoyes);
              printf("texte envoye : %s", buffer);
          }
          else
              printf("Erreur : donnees non envoyees au serveur");
      
      
          while(boucle)
          {
              memset(buffer, 0, TAILLE_MAX);
              // on reçoit les données envoyées par le serveur
              nOctetsRecus = recv(sock, buffer, TAILLE_MAX-1, 0);
              if(nOctetsRecus != SOCKET_ERROR)
              {
                  printf("%d octets ont ete recus\n", nOctetsRecus);
                  printf("texte recu : %s", buffer);
                  if (strstr(buffer, "PING") != NULL && buffer[0] == 'P')
                  {
                      buffer[1] = 'O';
                      send(sock, buffer, sizeof(buffer), 0);
                      printf("texte envoye : %s", buffer);
                      boucle = 0;
                  }
              }
              else
                  printf("Les donnees n'ont pas ete recues");
          }
      
          // on ferme la connexion
          closesocket(sock);
      
      
          #if defined (WIN32)
              WSACleanup(); // libère les ressources allouées par la fonction WSAStartup()
          #endif
      
          getchar();
      
          return EXIT_SUCCESS;
      }
      • Partager sur Facebook
      • Partager sur Twitter
      And those who were seen dancing were thought to be insane by those who could not hear the music.
        14 septembre 2017 à 0:32:46

        B'soir,

        Pas lu la doc, mais il me semble que le ping/pong ne sert à s'assurer qu'il n'y a pas déconnexion (sauvage) du client. Il doit être envoyer régulièrement par le serveur en cas d'inactivité du client.

        Tu dois pouvoir faire plein d'autres commandes (lister les cannaux/ rejoindre un canal)...) au lieu d'attendre le "ping"...

        • Partager sur Facebook
        • Partager sur Twitter
        ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
          18 septembre 2017 à 11:35:13

          En effet, c'est bien ça. Cependant, avant "d'automatiser" le PING/PONG, j'ai tenté de rejoindre un canal en ajoutant la portion de code suivant après la boucle :

              // le client envoie des données au serveur
              memset(buffer, 0, TAILLE_MAX);
              sprintf(buffer, "JOIN #root-me_challenge\r\n");
              tailleBuffer = strlen(buffer);
          
              nOctetsEnvoyes = send(sock, buffer, tailleBuffer, 0);
              if(nOctetsEnvoyes != SOCKET_ERROR)
              {
                  printf("%d octets envoyes au serveur\n", nOctetsEnvoyes);
                  printf("texte envoye : %s", buffer);
              }
              else
                  printf("Erreur : donnees non envoyees au serveur");
          
              // on reçoit les données envoyées par le serveur
              memset(buffer, 0, TAILLE_MAX);
              nOctetsRecus = recv(sock, buffer, TAILLE_MAX-1, 0);
              if(nOctetsRecus != SOCKET_ERROR)
              {
                  printf("%d octets ont ete recus\n", nOctetsRecus);
                  printf("texte recu : %s", buffer);
              }
              else
                  printf("Les donnees n'ont pas ete recues");


          Mais voilà ce que je récolte :

          Est-ce dû au fait que le serveur reçoit trop de données ?

          • Partager sur Facebook
          • Partager sur Twitter
          And those who were seen dancing were thought to be insane by those who could not hear the music.
            18 septembre 2017 à 11:47:45

            https://wiki.inspircd.org/Recvq

            après faut bien étudier le protocole...

            Que vaut TAILLEMAX pour le buffer?

            • Partager sur Facebook
            • Partager sur Twitter
            ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
              18 septembre 2017 à 21:05:01

              TAILLEMAX vaut 10000, ce qui je pense est largement suffisant, non ?

              • Partager sur Facebook
              • Partager sur Twitter
              And those who were seen dancing were thought to be insane by those who could not hear the music.
                18 septembre 2017 à 21:55:17

                Oui c'est suffisant...

                en cherchant"irc recvq exceeded" sur google, sur certains sujets, ils evoque le fait que trop de commendes sont envoyées trop vite successivement! Mets un petit Sleep() entre chaque envoie peut être? (500ms / 1s)

                • Partager sur Facebook
                • Partager sur Twitter
                ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
                  19 septembre 2017 à 17:37:26

                  J'ai essayé Sleep() en variant de 1 à 3 secondes, mais malheureusement ça ne change rien, toujours ce "RecvQ exceeded"...
                  • Partager sur Facebook
                  • Partager sur Twitter
                  And those who were seen dancing were thought to be insane by those who could not hear the music.
                    19 septembre 2017 à 18:54:39

                    Hoeplem a écrit:

                    J'ai essayé Sleep() en variant de 1 à 3 secondes,

                    Donc des valeurs de Sleep de 1000 à 3000, c'est bien ca? Bon je ne sais pas trop autrement, faut que vous potassiez la doc pour essayer de comprendre (et eventuellement vous renseignez sur le forum du serveur irc que vous cherchez à utiliser voir s'il a des réglages particulier?)
                    • Partager sur Facebook
                    • Partager sur Twitter
                    ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
                      19 septembre 2017 à 19:23:56

                      Oui, de Sleep(1000) à Sleep(3000). Je vais essayer de creuser et tester d'autres choses, merci en tout cas pour tes suggestions.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      And those who were seen dancing were thought to be insane by those who could not hear the music.

                      Connexion d'un client à un serveur IRC (sockets)

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown