X-Kalibur Posté(e) le 22 mai 2005 Partager Posté(e) le 22 mai 2005 Bon voila je débute en c++ et plus précisément dans les sockets, alors j'aurait aimer faire un server qui ce contente d'analyser tout les messages qu'on lui envoi et de répondre à certaine commande tel que le !salut, mais je n’y arrive pas... Alors j'ai commencer ce code à l'aide d'un tutorial mais j'arrive pas à le faire répondre aux messages dans le genre !salut. Et aussi si quelqu'un a une idée pourquoi il ne dit "Hello word" que quand on à envoyer le premier message et non quand on ce connect... Voici le code : #include <winsock2.h> /*socket*/ #include <stdio.h> /*printf*/ #pragma comment(lib, "ws2_32.lib") void main() { WSADATA WSAData; WSAStartup(MAKEWORD(2,0), &WSAData); SOCKET sock; SOCKET csock; SOCKADDR_IN sin; SOCKADDR_IN csin; char buffer[BUFSIZ];; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_family = AF_INET; sin.sin_port = htons(4444); sock = socket(AF_INET,SOCK_STREAM,0); bind(sock, (SOCKADDR *)&sin, sizeof(sin)); listen(sock,0); while(1) { memset(buffer, '\0', BUFSIZ); /*on vide le buffer*/ recv(csock, buffer, BUFSIZ-1, 0); printf("%s",buffer); int sinsize = sizeof(csin); csock = accept(sock, (SOCKADDR *)&csin, &sinsize); if(csock != INVALID_SOCKET) { send(csock, "Hello world!\r\n", 14, 0); } if(strstr(buffer,"!salut")) { sprintf(buffer, "Commen ça va ?\n"); send(csock, buffer, sizeof(buffer), 0); } } } Lien vers le commentaire Partager sur d’autres sites More sharing options...
keneda212 Posté(e) le 22 mai 2005 Partager Posté(e) le 22 mai 2005 ca va faire un bail que j'en ai pas fait (7_8 mois) mais y'a un truc qui me chagrine csock = accept(sock, (SOCKADDR *)&csin, &sinsize); tu accepte une socket mais tu la libère pas ? edit : j'ai creer un prog client et serveur qui communique entre eux pour s'echanger des fichier acec des connections socket. ca t'interresse pour voir comme j'ai fait ? edit 2 : moi j'accept pas des sockets. je me connecte a des sockets et je me deconnecter avec bind puis listen (pour le serveur) le client utilise connect mais quand j'y repense je fais ca en C et non en C++ Lien vers le commentaire Partager sur d’autres sites More sharing options...
X-Kalibur Posté(e) le 22 mai 2005 Auteur Partager Posté(e) le 22 mai 2005 Qu'entend tu par libérer... Je debute ^^. Lien vers le commentaire Partager sur d’autres sites More sharing options...
keneda212 Posté(e) le 22 mai 2005 Partager Posté(e) le 22 mai 2005 en fait, j'ai relu ton code et regarder le mien moi j'ai une boucle infini qui tourne si un client arrive, je lui attribut une socket, il se "connect" dessus le serveur l' "accept" comme tu l'a fait puis il discute puis je ferme la socket de communication avec un close(socket) donc un "close(csock)" dans ton cas mais ce n'est qu'une formalité pour evité de futur plantage en cas de soket non supprimé edit : lors de la lecture moi je fais read(descripteur de soket , buffer, taille a lire) mais apparement ton erreur viens du fait que tu lit dabord les données et apres tu accept la socket. ce devrait etre l'inverse je pense while(1) { memset(buffer, '\0', BUFSIZ); /*on vide le buffer*/ int sinsize = sizeof(csin); csock = accept(sock, (SOCKADDR *)&csin, &sinsize); if(csock != INVALID_SOCKET) { send(csock, "Hello world!\r\n", 14, 0); } recv(csock, buffer, BUFSIZ-1, 0); printf("%s",buffer); if(strstr(buffer,"!salut")) { sprintf(buffer, "Commen ça va ?\n"); send(csock, buffer, sizeof(buffer), 0); } } Lien vers le commentaire Partager sur d’autres sites More sharing options...
X-Kalibur Posté(e) le 22 mai 2005 Auteur Partager Posté(e) le 22 mai 2005 OK OK je vais tester. edit: Nan ça n'a rien changer. J'ai toujours les meme probleme : Je lance mon serveur ensuite je fais connecter mon client dessus, la j'envoie un message au serveur, il affiche le message a l'écran me répond par "Hello world" ensuite sur le client je peut renvoyer un autre message mais il ne s'affiche plus sur le serveur. Et le serveur ne répond pas non plus lorsque j'envois "!salut". Code du client : #include <winsock2.h> /*socket*/ #include <stdio.h> /*printf*/ #include <iostream> #pragma comment(lib, "ws2_32.lib") void main() { char ip[256]; std::cout << "IP : "; std::cin >> ip; std::cout << std::endl; WSADATA WSAData; WSAStartup(MAKEWORD(2,0), &WSAData); SOCKET sock; SOCKADDR_IN sin; char buffer[BUFSIZ]; char msg[256]; sin.sin_addr.s_addr = inet_addr(ip); sin.sin_family = AF_INET; sin.sin_port = htons(4444); sock = socket(AF_INET,SOCK_STREAM,0); bind(sock, (SOCKADDR *)&sin, sizeof(sin)); connect(sock, (SOCKADDR *)&sin, sizeof(sin)); while(1) { std::cout << "MSG : "; std::cin >> msg; sprintf(buffer, "%s\n", msg); send(sock, buffer, sizeof(buffer), 0); memset(buffer, '\0', BUFSIZ); /*on vide le buffer*/ recv(sock, buffer, BUFSIZ-1, 0); printf("%s",buffer); } }/* fin du programme */ Lien vers le commentaire Partager sur d’autres sites More sharing options...
X-Kalibur Posté(e) le 22 mai 2005 Auteur Partager Posté(e) le 22 mai 2005 Au passage j'ai rajouter un closesocket() a la fin de la boucle sur le serveur et maintenant je peut envoyer autant de commande que je veux sur le serveur mais ce dernier n'affiche que la première. while(1) { memset(buffer, '\0', BUFSIZ); /*on vide le buffer*/ int sinsize = sizeof(csin); csock = accept(sock, (SOCKADDR *)&csin, &sinsize); if(csock != INVALID_SOCKET) { send(csock, "Hello world!\r\n", 14, 0); } recv(csock, buffer, BUFSIZ-1, 0); printf("%s",buffer); if(strstr(buffer,"!salut")) { sprintf(buffer, "Commen ça va ?\n"); send(csock, buffer, sizeof(buffer), 0); } closesocket(csock); } } Lien vers le commentaire Partager sur d’autres sites More sharing options...
X-Kalibur Posté(e) le 22 mai 2005 Auteur Partager Posté(e) le 22 mai 2005 Lien vers le commentaire Partager sur d’autres sites More sharing options...
keneda212 Posté(e) le 22 mai 2005 Partager Posté(e) le 22 mai 2005 c bon tu peux enlever ton adresse mail je t'envoie ca dès que je peux edit : mdr je viens de trouver c'est toujours l'erreur conne qui est la plus dur if(csock != INVALID_SOCKET) { send(csock, "Hello world!\r\n", 14, 0); } si csock n'est pas une socket invalide en francais : si csock est une bonne socket faire envoye hello world donc si tu fait ca if(csock == INVALID_SOCKET) { send(csock, "Hello world!\r\n", 14, 0); } ca devrai fonctionner et vire la fermeture de socket dans le while(1) du serveur en fait dans ton cas ca sert a rien, faudrai le mettre apres le while(1) donc ca sert a rien de le mettre Lien vers le commentaire Partager sur d’autres sites More sharing options...
X-Kalibur Posté(e) le 22 mai 2005 Auteur Partager Posté(e) le 22 mai 2005 C'est bon en effet il répond bien au !salut. Mais il reste une petit problème, quand j'envoit "!salut" il me repond bien par "Ca va ?". Mais une fois qu'il ma répondu j'ai beau lui renvoyer "!salut" il ne repond plus... Et puis , if(csock == INVALID_SOCKET) { send(csock, "Hello world!\r\n", 14, 0); } En gros il ne sert pas a grand chose alors autant le supprimer nan ? edit: En effet ça sert à rien ça marche très bien sans. Mais j'ai toujours pas réussit a faire en sorte qui réponde toujours... Lien vers le commentaire Partager sur d’autres sites More sharing options...
keneda212 Posté(e) le 22 mai 2005 Partager Posté(e) le 22 mai 2005 le supprimer : c'est pas bien en fait ca fais parti de la gestion des erreurs si il y a un pb dans la connection des sockets, avec ce que tu a enlever, tu aura pu savoir que cela venais de la parcontre if(csock == INVALID_SOCKET) { send(csock, "Hello world!\r\n", 14, 0); } ca sert a rien je decode en francais : si la socket n'est pas valide, envoyer hello world par la socket archi null comme code d'erreur je ferai plutot if(csock == INVALID_SOCKET) { printf("erreur de connection socket"); } pour l'autre pb, tu a bien enlever le closesocket(csock); dans le server ? edit : y'a un truc qui est bizarre : tu fait du C++ ou du C car je vois que des fonctions C dans ton code de plus les #include, incluse des fonctions C comme printf Lien vers le commentaire Partager sur d’autres sites More sharing options...
X-Kalibur Posté(e) le 22 mai 2005 Auteur Partager Posté(e) le 22 mai 2005 Oui si tu veux comme code j'ai ça pour le moment : #include <winsock2.h> /*socket*/ #include <stdio.h> /*printf*/ #pragma comment(lib, "ws2_32.lib") void main() { WSADATA WSAData; WSAStartup(MAKEWORD(2,0), &WSAData); SOCKET sock; SOCKET csock; SOCKADDR_IN sin; SOCKADDR_IN csin; char buffer[BUFSIZ];; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_family = AF_INET; sin.sin_port = htons(4444); sock = socket(AF_INET,SOCK_STREAM,0); bind(sock, (SOCKADDR *)&sin, sizeof(sin)); listen(sock,0); while(1) { memset(buffer, '\0', BUFSIZ); /*on vide le buffer*/ int sinsize = sizeof(csin); csock = accept(sock, (SOCKADDR *)&csin, &sinsize); recv(csock, buffer, BUFSIZ-1, 0); printf("%s\n",buffer); if(strstr(buffer,"!salut")) { sprintf(buffer, "Commen ça va ?\n"); send(csock, buffer, sizeof(buffer), 0); } } } Franchement je voit pas d'ou ça peut venir, peut-être du coté du client ? edit: Y'a les deux ^^ enfin du c++ juste pour les cin et cout si tu veux y'a une partie qui date de y'a lontemps et l'autre que je viens de reprendre en c++ c'est plus rapide je trouve, mais bon ça devrait pas être ça le problème? si ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
keneda212 Posté(e) le 22 mai 2005 Partager Posté(e) le 22 mai 2005 #include <winsock2.h> /*socket*/ #include <stdio.h> /*printf*/ #pragma comment(lib, "ws2_32.lib") void main() { WSADATA WSAData; WSAStartup(MAKEWORD(2,0), &WSAData); SOCKET sock; SOCKET csock; SOCKADDR_IN sin; SOCKADDR_IN csin; char buffer[BUFSIZ];; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_family = AF_INET; sin.sin_port = htons(4444); sock = socket(AF_INET,SOCK_STREAM,0); bind(sock, (SOCKADDR *)&sin, sizeof(sin)); listen(sock,0); /* connection socket */ int sinsize = sizeof(csin); csock = accept(sock, (SOCKADDR *)&csin, &sinsize); while(1) { memset(buffer, '\0', BUFSIZ); /*on vide le buffer*/ recv(csock, buffer, BUFSIZ-1, 0); printf("%s\n",buffer); if(strstr(buffer,"!salut")) { sprintf(buffer, "Commen ça va ?\n"); send(csock, buffer, sizeof(buffer), 0); } } } essai comme ca edit de ton edit : ce n'est pas le probleme, c'est juste que quand tu code du C++ et qu'il y a des fonctions préfaite en C++ pour faire celle que tu utilise en C, c'est beaucoup plus propre c'est comme le mec qui fait du C++ et qui utilise des printf : code totalement pourrie faut voir avec la STL edit num 2 : c'est toujours bien de tester toutes les fonctions qui peuvent l'etre comme le bind et le listen qui renvoie des codes de retour et qui peuvent etre faux Lien vers le commentaire Partager sur d’autres sites More sharing options...
X-Kalibur Posté(e) le 22 mai 2005 Auteur Partager Posté(e) le 22 mai 2005 Aparement ça fonctionne plus bien du coter serveur mais : Voila ce que j'obtient du coter client : Je pense que ça vient plus du client cette fois si, enfin je te remercie déjà pour ça je vais essayer de me débrouiller maintenant. Si j'ai un problème je serais ou m'adresser ^^. Lien vers le commentaire Partager sur d’autres sites More sharing options...
keneda212 Posté(e) le 22 mai 2005 Partager Posté(e) le 22 mai 2005 probleme de buffer ou d'envoie de donnée : un truc dans le genre la boucle va peut etre trop vite... je réétudie ton code client pour voir #include <winsock2.h> /*socket*/ #include <stdio.h> /*printf*/ #include <iostream> #pragma comment(lib, "ws2_32.lib") void main() { char ip[256]; std::cout << "IP : "; std::cin >> ip; std::cout << std::endl; WSADATA WSAData; WSAStartup(MAKEWORD(2,0), &WSAData); SOCKET sock; SOCKADDR_IN sin; char buffer[BUFSIZ]; char msg[256]; sin.sin_addr.s_addr = inet_addr(ip); sin.sin_family = AF_INET; sin.sin_port = htons(4444); sock = socket(AF_INET,SOCK_STREAM,0); bind(sock, (SOCKADDR *)&sin, sizeof(sin)); connect(sock, (SOCKADDR *)&sin, sizeof(sin)); while(1) { std::cout << "MSG : "; std::cin >> msg; memset(buffer, '\0', BUFSIZ); /*on vide le buffer aussi ici */ sprintf(buffer, "%s\n", msg); send(sock, buffer, sizeof(buffer), 0); memset(buffer, '\0', BUFSIZ); /*on vide le buffer*/ recv(sock, buffer, BUFSIZ-1, 0); printf("%s",buffer); } }/* fin du programme */ j'ai rajouter le vidage du buffer. apres un tour de boucle tu ecrit dans le buffer sans le vider. mais bon ca ne doit pas venir de la je pense edit 1 : a force d'edite ca m'enerve. passage sur msn pour la suite ^^ Lien vers le commentaire Partager sur d’autres sites More sharing options...
X-Kalibur Posté(e) le 22 mai 2005 Auteur Partager Posté(e) le 22 mai 2005 Bon par manque d'envit de dormir j'ai finalement reussit à trouver le problème : remplacer tout les "BUFSIZ" et "BUFSIZE-1" par "sizeof(buffer)" et ça marche. Client : #include <winsock2.h> /*socket*/ #include <stdio.h> /*printf*/ #include <iostream> #pragma comment(lib, "ws2_32.lib") void main() { char ip[256]; std::cout << "IP : "; std::cin >> ip; std::cout << std::endl; WSADATA WSAData; WSAStartup(MAKEWORD(2,0), &WSAData); SOCKET sock; SOCKADDR_IN sin; char buffer[BUFSIZ]; char msg[256]; sin.sin_addr.s_addr = inet_addr(ip); sin.sin_family = AF_INET; sin.sin_port = htons(4444); sock = socket(AF_INET,SOCK_STREAM,0); bind(sock, (SOCKADDR *)&sin, sizeof(sin)); connect(sock, (SOCKADDR *)&sin, sizeof(sin)); while(1) { std::cout << "MSG : "; std::cin >> msg; memset(buffer, '\0', sizeof(buffer)); sprintf(buffer, "%s\n", msg); send(sock, buffer, sizeof(buffer), 0); memset(buffer, '\0', sizeof(buffer)); recv(sock, buffer, sizeof(buffer), 0); printf("%s\n",buffer); } } Server : #include <winsock2.h> /*socket*/ #include <stdio.h> /*printf*/ #pragma comment(lib, "ws2_32.lib") void main() { WSADATA WSAData; WSAStartup(MAKEWORD(2,0), &WSAData); SOCKET sock; SOCKET csock; SOCKADDR_IN sin; SOCKADDR_IN csin; char buffer[BUFSIZ];; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_family = AF_INET; sin.sin_port = htons(4444); sock = socket(AF_INET,SOCK_STREAM,0); bind(sock, (SOCKADDR *)&sin, sizeof(sin)); listen(sock,0); /* connection socket */ int sinsize = sizeof(csin); csock = accept(sock, (SOCKADDR *)&csin, &sinsize); while(1) { memset(buffer, '\0', sizeof(buffer)); /*on vide le buffer*/ recv(csock, buffer, sizeof(buffer), 0); printf("%s",buffer); if(strstr(buffer,"!salut")) { sprintf(buffer, "tu as dit salut\n"); send(csock, buffer, sizeof(buffer), 0); printf("rply-> %s\n",buffer); } if(strstr(buffer,"!hello")) { sprintf(buffer, "tu as dit hello\n"); send(csock, buffer, sizeof(buffer), 0); printf("rply-> %s\n",buffer); } } } Voila peut-être que ça poura aider quelqu'un. Et merci à keneda212. Lien vers le commentaire Partager sur d’autres sites More sharing options...
keneda212 Posté(e) le 23 mai 2005 Partager Posté(e) le 23 mai 2005 y'a juste un turc que je rajouterai pour faire plus propre et eviter des erreurs plus tard dans le serveur while(1) { memset(buffer, '\0', sizeof(buffer)); /*on vide le buffer*/ recv(csock, buffer, sizeof(buffer), 0); printf("%s",buffer); if(strstr(buffer,"!salut")) { memset(buffer, '\0', sizeof(buffer)); // vider le buffer car dans le cas ou tu ecris une chaine plus petite que celle que tu recoie, il te restera les caractères de fin du buffer precedent sprintf(buffer, "tu as dit salut\n"); send(csock, buffer, sizeof(buffer), 0); printf("rply-> %s\n",buffer); } if(strstr(buffer,"!hello")) { memset(buffer, '\0', sizeof(buffer)); // idem sprintf(buffer, "tu as dit hello\n"); send(csock, buffer, sizeof(buffer), 0); printf("rply-> %s\n",buffer); } } } Lien vers le commentaire Partager sur d’autres sites More sharing options...
savory Posté(e) le 23 mai 2005 Partager Posté(e) le 23 mai 2005 Je ne sais pas trop comment l'implementer en C++ mais je sais qu'il existe les selector de file descriptor en C ( le fameux FD_SET ) accessible depuis les fonctions select() et pselect(). L'avantage c'est que les sockets sont non bloquantes (asynchrone) , tu boucle sur ton set de fd et tu peux ainsi verifier si leur etats ( READ WRITE CONNECT ACCEPT) changent (ce mecanisme s'effectue via /dev/poll ) et en fonction de cela leur attacher une fonction donnée. En java on appele ca les NIO ( non blocking io ) et on peut leur attacher un handler directement ( c trop la classe je java ^^ ) En plus d'etre performant, ce fonctionnement est bcp plus logique a mon sens et permet de faire des handle de beaucoup de clients sans pour autant bouffer de la ressource ( un petit objet de pool de connexion a coté tu thread des workers apropriés et hop c fini :) ) Voila pour plus d'info man select Lien vers le commentaire Partager sur d’autres sites More sharing options...
keneda212 Posté(e) le 23 mai 2005 Partager Posté(e) le 23 mai 2005 c'est ce que je lui est conseillé quadn je lui ai refiler des sources d'un serveur mutliclient que j'ai concu pour du transfert de fichier par socket j'ai meme un tchat qui passe par des socket qui fonctionne ^^ Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.