IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Problème de sockets


Sujet :

C++

  1. #1
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut Problème de sockets
    Bonjour,

    J'ai actuellement un problème avec mon bot, je fais une while infinie pour et dans celle ci je vide le buffer puis vérifie son contenu. Tout d'abord je vérifie si l'information renvoyée par le serveur est une requête de PING, dans ce cas là je lui répond en lui renvoyant la requête nécessaire. Et lorsque cette information n'est pas une requête de PING mais un PRIVMSG, je vérifie s'il contient un certains mot et suivant ce mot j'envoie une requête. Seulement lorsque j'envoie cette requête, Les prochaines réponses aux requêtes de PING sont altéré.. Il n'envoie plus ce qu'il envoyait avant qu'il détecte le mot. Exemple

    -> N requête de ping
    <- N réponse à cette requête
    /* aucune erreur renvoyée */

    -> N requête de ping
    <- N réponse à cette requête
    -> PRIVMSG contenant le mot que je veux détecter
    <- envoie d'une requête
    -> N requête de PING
    <- N réponse à la requête
    -> envoie d'un message d'erreur


    Le message d'erreur ressemblant à:
    :serveur pseudo ²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²PING :Unknown command
    Je ne vois pas pourquoi lorsque je détecte ce mot dans un PRIVMSG, toutes mes réponses aux requêtes de PING qui suivent se trouvent altérée.

    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
     
    int main()
    {
    	WSADATA WSAData;
    	WSAStartup(MAKEWORD(2,0), &WSAData);
    	SOCKET sock;
    	SOCKADDR_IN sin;
     
    	char buffer[BUFSIZ]; 
    	char nick[] = "NICK squared\r\n", user[] = "USER socketz \"x.com\" \"irc.voila.fr\" :E equal MC squared\r\n", reply[] = "PONG :irc.voila.fr\r\n", join[] = "JOIN #help-scripting\r\n", version[]="";
     
    	sock = socket(AF_INET, SOCK_STREAM, 0);
    	sin.sin_addr.s_addr			= inet_addr("195.101.94.137");
    	sin.sin_family				= AF_INET;
    	sin.sin_port				= htons(6667);
     
    	connect(sock, (SOCKADDR *)&sin, sizeof(sin));
     
    	send(sock,user,strlen(user),0);
    	send(sock,nick,strlen(nick),0);
    	send(sock,join,strlen(join),0);
     
    	while (1) 
    	{
    		memset(buffer,'\0',BUFSIZ);
    		recv(sock,buffer,BUFSIZ-1,0);
    		if (buffer) {
    			cout<<buffer<<endl;
    			if (strstr(getTok(buffer,1,' '),"PING")) { send(sock,reply,strlen(reply),0); }
    			else if (strstr(getTok(buffer,2,' '),"PRIVMSG")) {
    				if (strstr(getTok(buffer,2,''),"VERSION")) { 
    					sprintf_s(version,BUFSIZ-1,"NOTICE %s :VERSION C.testing\r\n",getTok(getTok(buffer,1,'!'),2,':'));	
    					send(sock,version,strlen(version),0); 
    				}
    			}
    		}
    		else {
    			closesocket(sock);
    			WSACleanup();
    			system("PAUSE");
    			break;
    		}
    	}
    	return 0;
    }
    getTok(), est ma fonction qui me permet de parser les informations reçue par le serveur et renvoyant un const char *

    J'espère que vous aurez la solution à mon problème, car je ne vois vraiment pas comment cela est possible..

    Merci d'avance

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ben, déjà, tu peux passer BUFSIZ à sprintf_s(), sans le -1.

    Sinon, je ne connais pas le protocole d'IRC, mais tu es sûr qu'il ne faut pas envoyer les \0 ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut
    C'est ce que je fais c'est le \r, qui à ce rôle. Et pour le BUFSIZ, je vais faire la modification.

  4. #4
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut
    Bon j'ai essayé de raisonner et ai trouvé la solution. Ma requête se trouve dans un char qui se trouve altéré par je ne sais quel moyen, donc si je rend la valeur de ce char constante son contenu ne sera plus altéré.

    [edit]Même avec un const char, l'erreur se poursuit. Je crois que je vais devenir fou. Comment cela est-il possible ?![/dit]

  5. #5
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut
    Bon je fais une seconde fois appel à vous, car je fais face à un réel problème. Je ne vois pas comment cela est possible. Pour que vous compreniez de quoi je parle je vais rappeler mon problème.

    J'ai actuellement un problème avec mon bot, je fais une while infinie et dans celle ci je vide le buffer puis vérifie son contenu. Tout d'abord je vérifie si l'information renvoyée par le serveur est une requête de PING, dans ce cas là je lui répond en lui renvoyant la requête nécessaire. Et lorsque cette information n'est pas une requête de PING mais un PRIVMSG, je vérifie s'il contient un certains mot et suivant ce mot j'envoie une requête. Seulement lorsque j'envoie cette requête, Les prochaines réponses aux requêtes de PING sont altéré.. Il n'envoie plus ce qu'il envoyait avant qu'il détecte le mot. Exemple

    -> N requête de ping
    <- N réponse à cette requête
    /* aucune erreur renvoyée */

    -> N requête de ping
    <- N réponse à cette requête
    -> PRIVMSG contenant le mot que je veux détecter
    <- envoie d'une requête
    -> N requête de PING
    <- N réponse à la requête
    -> envoie d'un message d'erreur


    Le message d'erreur ressemblant à:
    :serveur pseudo ²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²PING :Unknown command
    Je ne vois pas pourquoi lorsque je détecte ce mot dans un PRIVMSG, toutes mes réponses aux requêtes de PING qui suivent se trouvent altérée.

    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
    64
    65
    66
    67
    68
    69
     
    #include <iostream>
    #include <stdio.h>
    #include <string>
    #include <cstring>
    #include <sstream>
    #include <cstdlib>
    #include <winsock2.h>
    #pragma comment(lib, "ws2_32.lib")
     
    using namespace std;
     
    const char *getTok(const char str[],const int pos,const char asc) {
    	istringstream iss(str);
    	string mot;
    	for(int i=1;i<=pos;i++) { getline(iss,mot,asc); }
    	size_t size = mot.size() + 1;
        char * buffer = new char[size];
    	strncpy_s(buffer,size,mot.c_str(),size);
    	return buffer;
    }
     
    int main()
    {
    	WSADATA WSAData;
    	WSAStartup(MAKEWORD(2,0), &WSAData);
    	SOCKET sock;
    	SOCKADDR_IN sin;
     
    	char buffer[BUFSIZ], version[] = ""; 
    	const char nick[] = "NICK squared\r\n",
    		user[] = "USER socketz \"x.com\" \"irc.voila.fr\" :E equal MC squared\r\n",
    		join[] = "JOIN #help-scripting\r\n",
    		reply[] = "PONG :irc.voila.fr\r\n";
     
    	sock = socket(AF_INET, SOCK_STREAM, 0);
    	sin.sin_addr.s_addr			= inet_addr("195.101.94.137");
    	sin.sin_family				= AF_INET;
    	sin.sin_port				= htons(6667);
     
    	connect(sock, (SOCKADDR *)&sin, sizeof(sin));
     
    	send(sock,user,strlen(user),0);
    	send(sock,nick,strlen(nick),0);
    	send(sock,join,strlen(join),0);
     
    	while (1) 
    	{
    		memset(buffer,'\0',BUFSIZ);
    		recv(sock,buffer,BUFSIZ-1,0);
    		if (buffer) {
    			cout<<buffer<<endl;
    			if (strstr(getTok(buffer,1,' '),"PING")) { send(sock,reply,strlen(reply),0); }
    			else if (strstr(getTok(buffer,2,' '),"PRIVMSG")) {
    				if (strstr(getTok(buffer,2,''),"VERSION")) {
    					sprintf_s(version,BUFSIZ,"NOTICE %s :VERSION C.testing\r\n",getTok(getTok(buffer,1,'!'),2,':'));	
    					send(sock,version,strlen(version),0);
    				}
    			}
    		}
    		else {
    			closesocket(sock);
    			WSACleanup();
    			system("PAUSE");
    			break;
    		}
    	}
    	return 0;
    }
    getTok(), est ma fonction qui me permet de parser les informations reçue par le serveur et renvoyant un const char *
    A aucun moment je n'envoie de requête "PING" au serveur, j'envoie la requête contenu dans mon const char reply. Reprenez moi si je me trompe mais étant constant sa valeur ne doit pas pouvoir être changé.. Donc comment celui-ci peut prendre une autre valeur que celle donnée au départ et surtout à quoi est dû ce changement de valeur..

  6. #6
    Fry
    Fry est déconnecté
    Membre régulier Avatar de Fry
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    150
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 150
    Points : 119
    Points
    119
    Par défaut
    Pas eu le courage de tout lire mais tu a essaye d'afficher le buffer que tu a envoye?
    Ca ressemble bcq a un pb de gestion de tes buffer char* ...

  7. #7
    Membre confirmé Avatar de Mayti4
    Inscrit en
    Février 2004
    Messages
    442
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 442
    Points : 488
    Points
    488
    Par défaut
    reply[] = "PONG :irc.voila.fr\r\n";
    Certains serveurs envoient un numéro qui peut changer je crois, faut vérifier dans la rfc.

    Une méthode est de remplacer le I de PING par un O et renvoyer la commande.
    memset(buffer,'\0',BUFSIZ);
    Inutile.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int ret = recv(sock,buffer,BUFSIZ-1,0);
    buffer[ret] = 0;
    if (buffer)
    Utilise la valeur retournée par recv.
    L'itération est humaine; la récursion, divine.

  8. #8
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (strstr(getTok(buffer,1,' '),"PING")) { send(sock,reply,strlen(reply),0); }
    Ce que j'envoie c'est ça.. donc reply et reply est un const char donc ça valeur est inchangeable et équivaut à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    reply[] = "PONG :irc.voila.fr\r\n";
    J'aimerais bien savoir comment en envoyant le contenu d'un const char je peux envoyer autre chose. Je ne suis tout de même pas fou!

  9. #9
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut
    Je vais en fait afficher la valeur de reply, avant l'envoie et voir ce qu'elle contient. Pour pouvoir mieux situer le problème. Je vous tiens au courrant.

  10. #10
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut
    Et bien je ne sais pas quoi vous répondre.. mon problème semble être résolu "comme par magie".. Il ne me renvoie plus d'erreur alors que je n'ai rien changé. Comme je vous l'ai dis j'ai commencé par afficher le contenu de reply, à la suite de l'affichage de celle ci j'ai pu observé qu'aucune erreur m'était renvoyée. J'ai donc décidé de virer l'affichage de sa valeur et pas de problème non plus. Tout roule, j'aurais tout de même préfèré une erreur histoire de moins passer pour un con mais bon. Vous me direz, il n'y avait aucune raison que cela ne marche pas! Merci pour vos réponses et vos remarques =]

  11. #11
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Il semblerait que tu n'aies pas compris la base, à savoir que les différents messages sont séparés par des retours à la ligne.
    Boost ftw

  12. #12
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut
    Si tu parles des messages envoyés, ce serait plutôt finit par des retours à la ligne et non séparé. Et si chaque requêtes n'étaient pas finie par un retour, le serveur n'appliquerait pas mes requêtes.

  13. #13
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Je fais allusion à la façon dont tu récupères les messages, qui est erronée.
    Il ne faut lire que jusqu'au caractère LF, ou alors lire ce qui est disponible et ensuite découper en plusieurs lignes traitées les unes après les autres.
    Boost ftw

  14. #14
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut
    Oui je sais, mais je ne l'ai pas encore traité effectivement. Ca ne serait tardé, merci du rappel je devais le faire mais avait mit ça de côté même trop de côté apparemment..

    [edit]
    Je viens de réfléchir pour ce qui est de lire jusqu'a LF, mais cela ne m'est pas utile puisque je parse mon texte.. Donc je ne traite qu'une partie de ce qui est reçu, celle qui m'intéresse qui plus est.
    [/edit]

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je ne sais pas si ça buggue toujours chez toi, mais le buffer version possède une taille de 1...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Membre averti Avatar de alceste
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 318
    Points : 356
    Points
    356
    Par défaut
    Non ça ne bug pas, mais je vais tout de même corriger ça..

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de sockets
    Par the_penguin dans le forum Réseau
    Réponses: 8
    Dernier message: 13/04/2006, 19h19
  2. Problême de Socket avec un applet java (RMI/policy)
    Par Vesperal dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 12/04/2006, 12h00
  3. Réponses: 2
    Dernier message: 26/03/2004, 09h15
  4. [Kylix] Problème de socket
    Par RaygKross dans le forum EDI
    Réponses: 1
    Dernier message: 01/03/2004, 19h41
  5. Mysql ne se lance pas problème de socket
    Par Riko dans le forum Installation
    Réponses: 5
    Dernier message: 05/02/2004, 09h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo