Socket, connection ok, premier envoi ok, mais après... ?

sabugo Messages postés 20 Date d'inscription vendredi 6 février 2004 Statut Membre Dernière intervention 16 juillet 2005 - 12 juil. 2005 à 00:56
sabugo Messages postés 20 Date d'inscription vendredi 6 février 2004 Statut Membre Dernière intervention 16 juillet 2005 - 12 juil. 2005 à 14:40
Bonjour !!



Voilà. Je dois créer un mini serveur socket capable de communiquer
quelques informations à une animation Flash via son objet XMLSocket.

J'ai donc, après quelques heures de recherches et de tests, implémenté un serveur très basique.

La connection entre le client Flash et le serveur s'effectue
correctement, ainsi que l'envoi du premier message, mais ensuite, plus
rien, aucune notifications pour les requêtes suivantes...



Je ne suis pas un grand connaisseur, je reprend gentillement le C++. Un peu d'aide serait la bienvenue...





Egalement une autre question relative... Je ne comprend pas très bien
comment, si je fais une classe "Serveur.cpp", rediriger ensuite sur le
bon processus suivant la commande passée en paramètre... un switch qui
va rediriger sur une classe controller, par exemple ?? enfin, je reste
basique, mais est-ce qu'il y a des moyens éprouvés, ou bien on fait ça
comme on le pense ??



D'avance merci pour vos conseils :)







Voici mon code :



#include

#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")




#define MAXBUFLEN 100

#define MYPORT 2027




int main( int argc, char * argv[] )

{

WSADATA WSAData;




if (WSAStartup(MAKEWORD(2, 0), &WSAData) != 0)

{

fprintf(stderr, "WSAStartup failed.\n");

exit(1);

}




SOCKET sock;

SOCKET csock;

SOCKADDR_IN sin;

SOCKADDR_IN csin;

int msgsize, sinsize, numbytes;

char buff[MAXBUFLEN];




sock = socket(AF_INET, SOCK_STREAM, 0);

sin.sin_addr.s_addr = inet_addr("127.0.0.1");

sin.sin_family = AF_INET;


sin.sin_port =
htons(MYPORT);

memset(&(sin.sin_zero), '\0', 8); // zero the rest of the struct











if (bind(sock, (SOCKADDR *)&sin, sizeof(sin)) == -1)

{

fprintf(stderr, "Bind failed.\n");

exit(1);

}




if( listen(sock, 0) == -1 )

{

fprintf(stderr, "Listen on socket failed.\n");

exit(1);

}




char* message = "Hello world, yeyeye !\r\n";

msgsize = strlen(message) + 1;




while(1)

{

sinsize = sizeof(csin);

if((csock accept(sock, (SOCKADDR *)&csin, &sinsize)) -1 ) //INVALID_SOCKET)

{

fprintf( stderr, "accept connection" );

continue;

}

fprintf( stderr, "server : got connection from %s\n", inet_ntoa( csin.sin_addr ) );




if( numbytes =recv( csock, buff, MAXBUFLEN - 1, 0) <= 0 )

{

if( numbytes == 0 )

// connection closed...

fprintf( stderr, "connection closed...\n" );




else



perror( "recv" );

}




fprintf( stderr, buff );

int bytes_sent = send(csock, message, msgsize, 0);

}

}

6 réponses

cs_AlexMAN Messages postés 1536 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 24 mai 2009 1
12 juil. 2005 à 08:45
while(1)
{
sinsize = sizeof(csin); if((csock accept(sock, (SOCKADDR *)&csin, &sinsize)) -1 ) //INVALID_SOCKET)
{
fprintf( stderr, "accept connection" );
continue;
}
fprintf( stderr, "server : got connection from %s\n", inet_ntoa( csin.sin_addr ) );

if( numbytes =recv( csock, buff, MAXBUFLEN - 1, 0) <= 0 )
{
if( numbytes == 0 )
// connection closed...
fprintf( stderr, "connection closed...\n" );

else

perror( "recv" );
}

fprintf( stderr, buff );
int bytes_sent = send(csock, message, msgsize, 0);
}
}

Ici ta boucle va en premier lieu accepter la connexion de ton client, puis recevoir le 1er message, mais ensuite tu reboucles en attendant une nouvelle fois une connexion...or celle ci n'arrive jamais puis ce que ton client est deja connecté ! donc il te suffit d'enlever accept() de la boucle, de laisser ta boucle comme elle est, mais tout de mm en laissant une condition de sortie (ta boucle est infinie la puis ce que tu n'as aucun break; pour en sortir...).

+2(p - n)
0
sabugo Messages postés 20 Date d'inscription vendredi 6 février 2004 Statut Membre Dernière intervention 16 juillet 2005
12 juil. 2005 à 11:43
Bonjour AlexMAN, et merci pour ta réponse :)



Y a un truc qui a du m'échapper, dans l'histoire des sockets... J'ai vu
plusieurs implémentations, et elles étaient toutes sous la forme :



while( !flag )

{

tester si on a une nouvelle connection

si oui, on ajoute le client

si non, tester si on a une réception

si oui, on la traite

si non, on ne fait rien

}



Ce que je n'arrive pas trop à comprendre dans ton raisonnement, c'est
que si j'enlève la commande "accept", le serveur ne tentera plus de
connecter des utilisateurs (même si il n'y en a qu'un seul), donc il ne
pourra pas non plus renvoyer d'infos à l'utilisateur...



C'est pas très net...

Dans mon esprit, si un utilisateur se connecte, il passe par la méthode
"accept", puis d'une fois qu'il est connecté, c'est un utilisateur
connu, donc on passe outre la méthode "accept", et on continue avec le
test sur "recv", non ??



Ma boucle est infinie, oui, c'est pour simuler un serveur socket, il
vaudrai mieux que ça tourne en boucle, sinon je ne vois pas l'intérêt...



Enfin bref, je ne pense pas qu'enlever l'accept va résoudre mon
problème, car il n'y aura plus aucun utilisateur de connecté... :(





Si tu as d'autres idées sur le sujet, je suis preneur, ou alors une
explication sur comment implémenter une boucle pour un serveur socket :)





Merci
0
cs_AlexMAN Messages postés 1536 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 24 mai 2009 1
12 juil. 2005 à 12:57
0
sabugo Messages postés 20 Date d'inscription vendredi 6 février 2004 Statut Membre Dernière intervention 16 juillet 2005
12 juil. 2005 à 14:03
Merci pour le lien, tout ceci est intéressant, et ça soulève un problème que je rencontre...



A ce que je sache, un serveur socket devrai tourner "indéfiniment" en
attente d'un connection ou de données reçues de la part d'un
utilisateur connecté.

Dans l'exemple Client-Serveur que tu m'as donné en lien, j'ai testé
compilé les sources et le résultat est que dès que le serveur à reçu
une connexion, il retourne un résultat et se ferme... C'est ici
qu'intervient mon incompréhension au niveau de cette fameuse boucle
while d'avant. Je pensais qu'elle était la justement pour permettre de
laisser le serveur tourner et tester si il reçoit une commande.



Donc à priori, je ne crois pas que ça soit si faux de mettre du code
dans le while, justement pour que le serveur tourne indéfiniment tant
qu'on ne lui ordonne pas de s'arrêter. Enfin, par rapport à mes
besoins, c'est ce que je devrai faire... Mais ça reste "pas très net" à
mes yeux...



Mais mon problème est peut-être un problème de transmission de Flash au
Serveur ou inversément. Je vais me renseigner auprès d'un ami qui
maitrise bien le sujet des sockets en Flash pour éloigner tous les
doutes ce propos.



Merci pour tes pistes.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
12 juil. 2005 à 14:35
Salut,

Tu peux pas faire un serveur qui accepte des connexions et traite toutes les requetes en une seule boucle while comme ca.



Il faut utiliser d'autres techniques, comme créer d'autres threads, ou
utiliser le modele select(), ou utiliser un autre modele dispo sous win
(WSAEventSelect, WSAAsyncSelect).
0
sabugo Messages postés 20 Date d'inscription vendredi 6 février 2004 Statut Membre Dernière intervention 16 juillet 2005
12 juil. 2005 à 14:40
hahaa, d'accord :) ceci explique celà.



Donc je vais essayer de faire des recherches plus approfondies sur le sujet. Si vous avez des urls à passer, je prend.



Merci beaucoup pour votre aide à tous les 2 ;)
0
Rejoignez-nous