Probléme pour lire le buffer au lancement de la connexion [Résolu]

Signaler
Messages postés
90
Date d'inscription
lundi 20 février 2006
Statut
Membre
Dernière intervention
6 mars 2007
-
Messages postés
1491
Date d'inscription
dimanche 19 novembre 2000
Statut
Modérateur
Dernière intervention
7 juillet 2014
-
Bonsoir, voila enfaite j'ai établi une connexion sur un server irc grace au socket mais quand je recois sur le buffer les différente informations (Elle arrive d'un coup au démarrage) et bein j'arrive pas a tous les traité comme on dirais que sa va trop vite pour le programme
alors il m'affiche les troix premiére phrase quand jlé traitre et aprés plus rien, alors existe-il un moyen de traité le données recu sur le buffer petit a petit ? ou un moyen de les stocker autrement?

vla le code

int main(int argc, char* argv[])
{
/* J'initialise ma socket */
WSADATA WSAData;
WSAStartup(MAKEWORD(2,0), &WSAData);
/* Je construit ma socket */
SOCKET sock;
SOCKADDR_IN sin;
char buffer[BUFSIZ];
char *ptr;
char msg[256];
char bp[512];

sock = socket(AF_INET, SOCK_STREAM, 0);


sin.sin_addr.s_addr = inet_addr(servip);
sin.sin_family = AF_INET;
sin.sin_port = htons(servport);
/* Fin de la construction de la socket */
/* Je me connect au server */
connect(sock, (SOCKADDR *)&sin, sizeof(sin));

while (1) {
/* Reception des données transmis par le server IRC */
memset(buffer, '\0',BUFSIZ);
recv(sock, buffer, BUFSIZ-1, 0);
/* J'envoi les données reçues dans la fenêtre windows */
printf("%s",buffer);
if (strstr(buffer, "PING :"))
{
ptr = strstr(buffer, "PING :") + strlen("PING :");
snprintf(msg, 256, "PONG :%s\n", ptr);
send(sock, msg, strlen(msg), 0);
}
if (strstr(buffer, "NICK"))
{
printf("pwet");
}
}
}

7 réponses

Messages postés
1491
Date d'inscription
dimanche 19 novembre 2000
Statut
Modérateur
Dernière intervention
7 juillet 2014

Ha pardon, retour était une constante qui pointait vers un tablo de 2 caractères.

Retour = {13, 10};
Mais tu peux très bien remplacer Retour par "\r\n" partout

http://vbaddons.free.fr
MSN : x_men_40(
Messages postés
1491
Date d'inscription
dimanche 19 novembre 2000
Statut
Modérateur
Dernière intervention
7 juillet 2014

Bon maintenant c'est moi qui te pose deux dernières question :D
- T'es Québecois ?
- T'as vraiment 10 ans ? (lol )

PS : Quand une réponse te satisfait il faut que tu la marque comme étant une réponse acceptée, ça aide à la recherche futur.

A+

http://vbaddons.free.fr
MSN : x_men_40(
Messages postés
1491
Date d'inscription
dimanche 19 novembre 2000
Statut
Modérateur
Dernière intervention
7 juillet 2014

NON !!! Raze moi ce code, brule-le, brule-le !!!

Oublie cette méthode, éfface de ta mémoire ... c'est bon ? ok je peux commencer mon explication

1) Sur un serveur IRC chaque commande se termine par deux caractères qui sont 13 et 10 (ou endl //endline) donc la seule façon de traiter d'une façon potable les données qui entrent c'est de les traiter ligne par ligne (13 et 10 étant des retour à la ligne). Une fois que tu aura un code pour ça tu seras en voiture et tu n'aura plus jamais de problème de traitement de ta vie ... une fonction Split ferait l'affaire avec quelques modifications.

2) Il se peut que la commande soit coupée en deux car elle arrive dans deux packets différents ! Il faut donc que ta fonction de traitement en tiennent compte et accumule dans un buffer les packets jusqu'a obtenir des commades complètes (tu peux traiter les données et garder ce qui est pas traitable pour ensuite additionner un packet au bout. Ça n'arrive pas souvent qu'une commande soie tronqués c'est vrai, mais ça peut arriver et tu dois absolument en ternir compte (ça dépend du niveau d'utilisation de la bande passante par le serveur et le client).

Voilà j'espère que ces infos t'auront été d'une utilité quelquonque.

Je termine avec un liens vers un programme fonctionnant sous un principe semblable :
http://vbaddons.free.fr/downloadsource/jaybayda%20ya%200.1.zip
Je le dépose pas ici car c'est le genre de programme que CS veut pas, mais tu peux étudier le système de traitement et l'améliorer. IL tient compte de tous ce que j'ai dis plus haut.

A+ Bonne prog

http://vbaddons.free.fr

if (CPossible)
Messages postés
90
Date d'inscription
lundi 20 février 2006
Statut
Membre
Dernière intervention
6 mars 2007

Tes explication son clairs sa ya pas a en douter, mais le probléme c que je pige quedale au programme que tu ma mis en lien. Donc il est pas possible que tu me face un exemple ? (Je sais que CS n'accepte pas ce genre de code) alors tu peux me le mettre en lien histoire que je comprenne a 100% ,
Messages postés
1491
Date d'inscription
dimanche 19 novembre 2000
Statut
Modérateur
Dernière intervention
7 juillet 2014

Alors oublie mon programme en liens

Ta fonction strstr() servira simplement à trouver des retours à la ligne au lieux des commandes comme ping. Tu n'as qu'a mettre dans un buffer ce qui arrive en accumulant, ensuite une deuxième fonction s'occupera du traitement ligne par ligne, une fois qu'une ligne est faite il suffit de la retirer du buffer et recommencer le processus jusqu'a ne plus trouver de retour de chariot, ça peut signifier soit qu'il n'y a plus rien à traiter, soit il reste quelque chose d'incomplet mais de toute façon on sort de la fonction de traitement. Une fois un nouveau packet arrivé il va s'additionner à ce qui restait dans le buffer non traité (s'il y a des octets non traités) et ainsi de suite.

Un petit exemple au niveau prog (je suis un débutant et un expert serait sûrement faire beaucoup mieux, mais je connais ces concepts car j'ai codé des applications rézo pendant longtemps en VB (et oui ex VBiste))

char Buffer[4096]; //Tu le met de la grosseur que tu veux, mais assure toi que si il en arrive plus il n'y aura pas d'explosion

//C'est un copier-coller un peu modifier d'un de met programme, ne pas se fier au contenu à 100%
//Dans ce cas c'était une thread car c'est le code d'un serveur que j'ai pris, mais tu peux utiliser les sockets asynchromes

void FonctionQuiRecois(ClientArbre *Client)
{
char tmpData[1024+1]; //Mettre un packet à la fois
Buffer[0] = 0; //Mettre le buffer à 0

while(1)
{
Fin = recv(Client->Socket, tmpData, 1024, 0);
if (Fin > 0)
{
tmpData[Fin] = 0; //Ajouter le caractère de fin de chaine

if (Fin + strlen(Buffer) < 4096) //Anti Overflow
strcat(Buffer, tmpData);

TraitementDonnee(Client);
}
else
break;
}
}

//Traitement des données
void TraitementDonnee(ClientArbre *Client)
{
int Pos = strstr(Buffer, Retour) - Buffer;
char Ligne[1024];

if (Pos < 0) //Si non trouvé on quitte la fonction
return;

if (Pos > 1024) //J'ai limité chaque ligne à 1024 caractères seulement !! Sinon on efface le buffer
{
ZeroMemory(Buffer, 4096); //Tout détruires
return;
}

do
{
CopyMemory(Ligne,Buffer, Pos); //On veut une ligne à la fois
Ligne[Pos] = 0; //CopyMemory ne met pas le caractère 0

//C'EST ICI QUE TU TRAITE CHAQUE COMMANDE !!

strcpy(Buffer, Buffer + Pos + 2); //Éliminer la ligne

Pos = strstr(Buffer, Retour) - Buffer;
}
while (Pos >= 0 && Pos <= 1024); //Si strstr retourne une valeur négative alors on quitte la fonction c'est que c'est imcomplet ou terminé

}

J'espère que ça t'aidera plus, si un expert passe dans le coin qu'il n'hésite pas à commenter surtout :D (Qui a parlé de BN ? hum j'ai rien fait )

Hésite pas a en demander d'avantage (mais je vais être plus lent à répondre étant donné que j'aurai internet seulement 1h ou 2 certain jour)

A+

http://vbaddons.free.fr
MSN : x_men_40(
Messages postés
90
Date d'inscription
lundi 20 février 2006
Statut
Membre
Dernière intervention
6 mars 2007

Je te remercie de ces explication donné avec ce code mais tu ne ma pas donné la variable 'Retour' donc je sais pas a koi elle correspond, ou si elle enmagasine une valeur...
Messages postés
90
Date d'inscription
lundi 20 février 2006
Statut
Membre
Dernière intervention
6 mars 2007

pté ba écoute jte remercie vraiment car le code marche impécable, j'arrive a traiter petit a petit les messages du buffer.

Vraiment génial, encore merci de m'avoir consacré du temps :)