Winsock fonction listen qui bloque

Signaler
Messages postés
42
Date d'inscription
mercredi 17 novembre 2004
Statut
Membre
Dernière intervention
22 janvier 2006
-
cs_aardman
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
-
Bonjour voila je suis entrain d'effectuer un programme avec winsock en
graphique mais j'ai un probleme arrivé sur une boucle d'ecoute. Quand
un client arrive elle doit sortir de celle ci. mais le probleme c'est
que cette fonction marche en mode console mais pas en graphique, sa
fait planter le programme!! la fonction que je parle est :
listen(idSocket,1);.

ban dans ma classe, j'ai crée une méthode pour pouvoir mettre soit TCP ou UDP dans la meme sa donne sa :

(je cherche apres l'icone pour inserer du code comme ds vb france mais je trouve pas ??? c'est où???)









SOCKET Cclassewinsock::UDPTCP(CString type)

{

iErreur=WSAStartup(MAKEWORD(2,0),&WSAData);//initialisation de winsock

Socketaddr_in.sin_addr.S_un.S_addr =inet_addr("127.0.0.1");//adresse locale du serveur

Socketaddr_in.sin_family= AF_INET;

Socketaddr_in.sin_port=htons(1080);//valeur du port sur lequel on va ecouter

if(type=="SOCK_STREAM")

{

idSocket=socket(AF_INET,SOCK_STREAM,0);//creation du socket tcp

iErreur=100;//initialisation de erreur pour pouvoir entrer dans la boucle

while(iErreur!=0)//boucle tant qu'une session n'a pas été recu


iErreur=listen(idSocket,1); //pb ici qui fait planter le prog or qu'en
console sa marche

itemp=sizeof(InfosourceAccept);


idSocketEchange=accept(idSocket,(struct sockaddr*) &
InfosourceAccept,&itemp);//on accepte la connexion d'un client

}

else

{

idSocket=socket(AF_INET,SOCK_DGRAM,0);//creation du socket udp

}

iBind=bind(idSocket,(SOCKADDR *)&
Socketaddr_in,sizeof(Socketaddr_in));//lien entre socket et les info du
serveur

return idSocket;

}



Merci bcp de votre aide



wazaaa breton

12 réponses

Messages postés
42
Date d'inscription
mercredi 17 novembre 2004
Statut
Membre
Dernière intervention
22 janvier 2006

j'ai trouver deja un pb, il fallait mettre bind avant que sa ne soit en
ecoute. Mais j'ai toujours un pb de plantage quand il arrive sur accept.

idSocketEchange=accept(idSocket,(struct sockaddr*) & InfosourceAccept,&itemp);//on accepte la connexion d'un client

La je ne sais pas pourquoi sa fait sa .... mais il reste bloqué là ce
qui est normal puisqu'il attend un client mais sa fait planter le prog
vous avez une proposition sur le pb???

wazaaa breton
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,

Met le code, et sois plus précis que "ca fait planter le prog".
Messages postés
42
Date d'inscription
mercredi 17 novembre 2004
Statut
Membre
Dernière intervention
22 janvier 2006

voila ma methode tcp, qui gere le client et le serveur a la fois:

SOCKET Cclassewinsock::UDPTCP(CString type, int temp)

{

iErreur=WSAStartup(MAKEWORD(2,0),&WSAData);//initialisation de winsock

Socketaddr_in.sin_addr.S_un.S_addr =inet_addr("127.0.0.1");//adresse locale du serveur

Socketaddr_in.sin_family= AF_INET;

Socketaddr_in.sin_port=htons(1080);//valeur du port sur lequel on va ecouter

if(temp==0)//ici on test si on a demander d'etre serveur

{

if(type=="SOCK_STREAM")

{


idSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//creation du socket
tcp


iErreur=100;//initialisation de erreur pour pouvoir entrer dans la
boucle


iBind=bind(idSocket,(SOCKADDR *)&
Socketaddr_in,sizeof(Socketaddr_in));//lien entre socket et les info du
serveur

while(iErreur!=0)//boucle tant qu'une session n'a pas été recu

iErreur=listen(idSocket,1);

itemp=sizeof(InfosourceAccept);


idSocketEchange=accept(idSocket,(struct sockaddr*) &
InfosourceAccept,&itemp);//on accepte la connexion d'un client

}

else

{

idSocket=socket(AF_INET,SOCK_DGRAM,0);//creation du socket udp


iBind=bind(idSocket,(SOCKADDR *)&
Socketaddr_in,sizeof(Socketaddr_in));//lien entre socket et les info du
serveur

}

}

else//ici c'est la parti cliente

{

if(type=="SOCK_STREAM")

{

idSocket=socket(AF_INET,SOCK_STREAM,0);//creation du socket


iErreur=connect(idSocket,(struct
sockaddr*)&InfosourceAccept,sizeof(InfosourceAccept));

}

else

{

idSocket=socket(AF_INET,SOCK_DGRAM,0);//creation du socket udp

}

}



return idSocket;

}



lorsque je fait un debug, celui-ci s'arrete sur
idSocketEchange=accept(idSocket,(struct sockaddr*) &
InfosourceAccept,&itemp);//on accepte la connexion d'un client.

Ce qui est normal puisqu'il attend la connexion d'un client. Cependant
le programme s'arrete ici et bloque. Quand je lance mon client je
n'arrive pas a me connecter sur le serveur.Et quand je vais voir le
serveur, celui-ci est planté.Aucune action est possible dessus.

wazaaa breton
Messages postés
146
Date d'inscription
jeudi 22 avril 2004
Statut
Membre
Dernière intervention
8 mars 2008
1
Salut, je pense qu'il faut d'abord fermer le sock avant d'accepter.

comme dans vb !



<ol>
<li>

</li>
</ol>
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,

Pour bind et listen, il ne faut pas faire de boucle: soit tout va bien
et les fonctions retournent 0, soit il y a un probleme et elles
retourent SOCKET_ERROR. Dans ce cas la, il faudrait afficher le numero
de l'erreur retourné par WSAGetLastError().

Meme remarque pour socket(), si la fonction retourne INVALID_SOCKET il faut afficher le numero de l'erreur.
Messages postés
42
Date d'inscription
mercredi 17 novembre 2004
Statut
Membre
Dernière intervention
22 janvier 2006

C'est ce qu ej'ai fait dans ma partie graphique. Si iErreur est different de 0 alors il faut dire le pb...

Ensuite pour les boucle ok j'ai virer la boucle pour le listen.

Ensuite pour mon accept le probleme est toujours la.

Mais il faut que je ferme le socket comme la dit [auteurdetail.aspx?ID=265433 MrdJack]??? avant de faire accept?

wazaaa breton
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,

et alors ? tu obtiens quoi comme erreur, et a quelle fonction ?
Messages postés
42
Date d'inscription
mercredi 17 novembre 2004
Statut
Membre
Dernière intervention
22 janvier 2006

a la fonction accept :

idSocketEchange=accept(idSocket,(struct sockaddr*) & InfosourceAccept,&itemp);

le programme s'arrete, ce qui est normal puisqu'il attend un client.
Mais l'application se fige, je n'est plus acces a aucun bouton comme
quitter et l'application doit etre fermer avec ctrl alt suppr, chose
qui n'est pas normal car en mode console no probleme sur cette fonction.

wazaaa breton
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,

Ah ben si tu n'es pas en console, c'est normal que l'application se
fige, car accept() bloque le thread, et donc les messages de ta fenetre
ne sont plus traités.

Pour resoudre ce probleme, soit tu peux utiliser accept() dans un
thread, soit tu peux utiliser les sockets non bloquants (sous windows
il y a le modele WSAAsyncSelect() qui est tres bien).
Messages postés
42
Date d'inscription
mercredi 17 novembre 2004
Statut
Membre
Dernière intervention
22 janvier 2006

Ok j'ai compris le principe du thread. J'ai trouvé sur le forum
l'utilisation de la fonction select() avant accept et autre comme recv.
Est ce que c'est une bonne idée ?

par contre pour les parametres a lui donner, je peut trouver sa sur la msdn ?
wazaaa breton
Messages postés
42
Date d'inscription
mercredi 17 novembre 2004
Statut
Membre
Dernière intervention
22 janvier 2006

Ban j'ai trouvé les parametres a lui filer. par contre j'aimerai savoir
a quoi correspond les variables a declarer pour ce type :

FD_ZERO

FD_SET

timeval ( sa c'est pour le temps ) elle est inclu dans winsock2.h ?

wazaaa breton
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,

select() te permetra de gerer plusieurs sockets dans ton thread (celui
qui écoute et ceux de tes clients qui se connectent), mais tu n'es pas
obligé de l'utiliser.

Pour savoir comment utiliser select() tu peux lire le chapitre 5 de cet ebook:

http://betouchi.free.fr/doc_et_ebook/prog_reseau/network2.chm