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;
}
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;
}
And those who were seen dancing were thought to be insane by those who could not hear the music.
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"...
** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
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 ?
And those who were seen dancing were thought to be insane by those who could not hear the music.
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)
** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
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?)
** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
Oui, de Sleep(1000) à Sleep(3000). Je vais essayer de creuser et tester d'autres choses, merci en tout cas pour tes suggestions.
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.