Ah ben merci, je savais pas, je me suis fié au man.Envoyé par Emmanuel Delahaye
Au temps pour moi.
Ah ben merci, je savais pas, je me suis fié au man.Envoyé par Emmanuel Delahaye
Au temps pour moi.
Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
Mon espace perso[/B]
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]
oui excuse moin je voulais dire client...
Le serveur, ne communique qu'avec un seul des client, meme si j'en lance deux (chacun dans un terminal ,different biensur), le serveur, fait comme si il n'y'en avait qu'un seul.
Je comprends pas pourquoi, j'ai bien fait un select dans le serveur...
Et pour bzero(), le prof utilise cette fonction, donc je dois en faire de meme.
Merci pour les corrections.
Ben c'est plus le code du serveur qu'il nous faut.Envoyé par juve1897
Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
Mon espace perso[/B]
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]
Mon code du serveur est en PJ...
Merci de m'apporter ton aide...
Le code est assez horrible mais je vois un gros probleme.
Tu utilises très mal le select et le accept.
En fait tu dois ajouter à ton fd_set les sockets clients et la socket de ton serveur (celle du accept).
Lorsque que select est déclanché tu regardes quel socket parle. Si c'est un client tu fais ce qu'il y a à faire, si c'est la socket de connexion tu fais un accept (pour accepter le nouveau client).
Au fait pas besoin de compter le nombre de joueur, lors tu listen tu met 2 en second paramètre, comme ça le serveur n'acceptera que 2 clients à la fois.
Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
Mon espace perso[/B]
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]
Je ne suis pas sûr que ce paramètre de listen() serve à ça. J'ai cru comprendre qu'il dimensionnait la file de sérialisation des demandes de connexion simultanées. Il ne limite pas le nombre de clients connectés en même temps. Ce nombre n'est, à ma connaissance, pas limitable (autrement que par comptage).Envoyé par Skyrunner
Pas de Wi-Fi à la maison : CPL
Moi j'avais cru comprendre que cette argument définissait la longueur maximale de la file de connexion. Pour les connexions en attente, et dès que cette file est pleine une erreur est envoyé au client qui tente de se connecter.Envoyé par Emmanuel Delahaye
Après je sais pas, je ne fais que lire le man
Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
Mon espace perso[/B]
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]
Envoyé par Skyrunner
Ah bon qu'est ce qu'il a d'horrible???
Mais bon tu dois aussi savoir que je ne connais le C que depuis 1an.
Ben c'est ce que je fais avecEnvoyé par Skyrunner
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 if(rval) { sock_service= accept(sock_ecoute, (struct sockaddr*)&client_adr, &lemis); if(sock_service < 0) { perror("Probleme accept "); exit(1); } while(cpt_j<2) { if(cpt_j==0) { FD_SET(sock_service,&fd); j1.desc=sock_service; j1.nom=nom[cpt_j]; }et c'est ce que je fais aussi avec ça:Envoyé par Skyrunner
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 if(FD_ISSET(j1.desc,&fd)) //teste si c'est la sock1 qui a envoyé le msg { data=invite_jeu(morpion,data); if(write(j1.desc,data,strlen(data)) < 0) //on lui envoie le jeu actuel { perror("write server"); exit(1); } morpion=traiterClient(sock_service,"CLIENT1",morpion); //on traite le client }
Ben je vois pas ce qui est faux. Enfin ce que je pense etre juste et qui ne l'est pas.
Est ce que tu pourrais STP m'éclairer un peu plus...
Voilà ce que dit POSIX.1 : (backlog est le 2ème paramètre de listen()) :Envoyé par Skyrunner
C'est pas d'une clarté phénoménale...The backlog argument provides a hint to the implementation which the implementation shall use to limit the number of outstanding connections in the socket's listen queue. Implementations may impose a limit on backlog and silently reduce the specified value. Normally, a larger backlog argument value shall result in a larger or equal length of the listen queue. Implementations shall support values of backlog up to SOMAXCONN, defined in <sys/socket.h>.
The implementation may include incomplete connections in its listen queue. The limits on the number of incomplete connections and completed connections queued may be different.
The implementation may have an upper limit on the length of the listen queue-either global or per accepting socket. If backlog exceeds this limit, the length of the listen queue is set to the limit.
If listen() is called with a backlog argument value that is less than 0, the function behaves as if it had been called with a backlog argument value of 0.
A backlog argument of 0 may allow the socket to accept connections, in which case the length of the listen queue may be set to an implementation-defined minimum value.
J'essaye de traduire :
"Le paramètre 'backlog' fourni une aide (indication, information ?) à l'implémentation que celle-ci doit utiliser pour limiter le nombre de outstanding connexions dans la file d'écoute du socket.
Les implémentations peuvent imposer une limite à la valeur du paramètre 'backlog' et à réduire silencieusement la valeur spécifiée. Normalement, une valeur de backlog plus grande devrait résulter en une file d'une taille supérieure ou égale. Les implémentations devraient supporter une valeur inférieure ou égale à la constante SOMAXCONN telle qu'elle est définie dans <sys/socket.h> [NdT ne pas confondre avec <socket.h>]
L'implémentation peut inclure les connexions incomplete (incomplètement établies ?) dans sa file d'écoute. Le nombre maximum de connexions complètes et incomplètes mises en files peuvent être différents.
[NdT je ne sais pas ce qu'est une 'connexion complète ou incomplète']
L'implémentation peut avoir une limite supérieur à la longueur de la file d'écoute, soit global (?) soit par socket acceptant une connexion (?).
[Ndt, c'est chaud, l'aide d'un anglophone est la bienvenue]
Si la valeur du paramètre 'backlog' dépasse cette limite, la taille de la file d'écoute est réglée à cette limite.
Si listen() est appelée avec une valeur du paramètre 'backlog' inférieur à 0, la fonction se comporte comme si elle avait été appelée aec un 'backlog' valant 0.
Un paramètre 'backlog' valant 0 doit permettre au socket d'accepter des connexions. Dans ce cas, la taille de la file d'écoute est ajustée à une valeur minimale définie par l'implémentation."
Pas de Wi-Fi à la maison : CPL
Ok, désolé j'avais un peu mal regardé.
Mais dans tous les cas, quand select se déclenche tu fais un accept dans tous les cas, et ça il faut pas.
Ensuite à ta premiere connexion, tu rentre dans ton while cpt_j = 0 ok, tu rentres dans le if tu place dans le fd_set le socket de ton client ok.
Ensuite tu fais un cpt_j ++ donc cpt_j = 1
Tu repars donc dans le while et là tu rentres dans le else de ton if et tu ajoutes le même socket dans ton fd_set.
Donc voilà le problème.
Revois ton algo je pense. Ce n'est pas un problème de conception mais d'algo à ce niveau.
Ravi de t'aider.
Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
Mon espace perso[/B]
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]
@Emmanuel : C'est bizarre, je comprends pas la même chose entre ceux que POSIX dit et ce que le man dit.
Je suppose donc que c'est POSIX qui a raison.
Envoyé par man
Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
Mon espace perso[/B]
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]
Merci beaucoup pour ces details, j'ai tellement de while, for, do while et if ... else que je m'en sors plus.
Hep, tu m'as toujours pas dit ce qu'il avait d'horrible mon code ???
Je vais revoir tout ça et je te tiens au courant...
Merci encore de m'avoir fait gagner un peu de temps.
Parce que ça fait plus de 3semaines que je suis deçu et je dois rendre ça dans 2semaines. J'ai encore un rapport à taper, alors faut pas que je perde trop de temps.
desolé de te souler à nouveau, mais je vois pas pourquoi je ne dois pas accepter de connexion suplementaire avec select.
comment alors je pourrais capter qu'un deuxieme client se connecte????
De plus j'ai changé le bout de code où tu me signalais que je mettais tjs la meme socket dans la file...
voilà:
Mais j'ai toujours le meme probleme, le serveur ignore le deuxieme client et ne communique qu'avec le premier.
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 while(cpt_j<2) //On compte le nombre de joueur (il ne peut en avoir que 2) { sock_service= accept(sock_ecoute, (struct sockaddr*)&client_adr, &lemis); /*...on l'accepte...*/ if(sock_service < 0) /*...toujours avec un test pour éviter les erreurs...*/ { perror("Probleme accept "); exit(1); } if(cpt_j==0) { FD_SET(sock_service,&fd); // On place notre nouveau descripteur de socket dans la file d'attente j1.desc=sock_service; // ainsi que que dans le champ de j1 j1.nom=nom[cpt_j]; // le pseudo est aussi stocké dans la structure } else { FD_SET(sock_service,&fd); // On place notre nouveau descripteur de socket dans la file d'attente j2.desc=sock_service; // ainsi que que dans le champ de j1 j2.nom=nom[cpt_j]; // le pseudo est aussi stocké dans la structure } cpt_j++; // incrementation du compteur de joueur if(FD_ISSET(j1.desc,&fd)) //teste si c'est la sock1 qui a envoyé le msg { data=invite_jeu(morpion,data); if(write(j1.desc,data,strlen(data)) < 0) //on lui envoie le jeu actuel { perror("write server"); exit(1); } morpion=traiterClient(sock_service,"CLIENT1",morpion); //on traite le client } else if(FD_ISSET(j2.desc,&fd)) { data=invite_jeu(morpion,data); if(write(j2.desc,data,sizeof(data)) < 0) { perror("write server"); exit(1); } morpion=traiterClient(sock_service,"CLIENT2",morpion); } } }
Peux tu me pister un peu plus, car là je vois pas quoi faire de plus.
J'ai l'impression que le serveur ne connecte pas mon deuxieme client, mais si c'etait le cas, la fonction connect m'aurait renvoyée un message d'erreur ! Non?
Bon je te donne un pseudo algo
A toi d'implementer en C.
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
18tant que vrai select si socket de connexion si nb client < 2 accept ajouter socket client au fd_set action nb client ++ fin si sinon pour chaque socket client si socket a parlé action fin si fin pour fin si fin tant que
Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
Mon espace perso[/B]
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]
deja merci pour le pseudo code, mais desolé d'etre lourd.
J'ai du mal a comprendre comment je pourrais mettre ça dans mon code.
Tu me dis de faire :
Mais si je code ça ainsi, je fais comment la difference entre le client 1 et 2???
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 tant que vrai select si socket de connexion si nb client < 2 accept ajouter socket client au fd_set action nb client ++ fin si sinon pour chaque socket client si socket a parlé action fin si fin pour fin si fin tant que
Car dans ma fonction traiterClient, je dois absolument differencier, le client 1 du client 2, pour savoir, si je mets une croix ou un rond dans le morpion...
Merci encore pour ton aide.
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 while(1) { FD_SET(sock_ecoute,&fd); //sock_ecoute contien le resultat de "bind" if(select(nb_client+1,&fd,....) { perror("select"); exit(1); } if(FD_ISSET(sock_ecoute,&fd) { if(cpt_j < 2) { sock=accept(sock_ecoute,....); FD_SET(sock,&fd); morpion=traiterClient(sock,morpion); cpt_j++; } } else { for(sock=0;sock<3;sock++) { if(FD_ISSET(sock,&fd)) morpion=traiterClient(sock,morpion); } } }
Toujours pas je reprends ton code et je mets des commentairesEnvoyé par juve1897
Bon j'ai même rajouter du code pour que ça marche normalement.
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 [...] typedef struct { int sock; char pseudo[100]; } Joueur; [...] int max = sock_ecoute; /* max sera le 1er argument de select (voir man) */ FD_SET(sock_ecoute, &fd); /* ajoute le ici sinon a chaque boucle du while tu le rajouteras */ Joueur tab[2]; while(1) { if(select(max+1,&fd,....) { perror("select"); exit(1); } if(FD_ISSET(sock_ecoute,&fd) { if(cpt_j < 2) { Joueur j; sock=accept(sock_ecoute,....); FD_SET(sock,&fd); j.sock = sock; tab[cpt_j] = j; max = sock > max ? sock : max; morpion=traiterClient(sock,morpion); cpt_j++; } } else { int i = 0; for(i=0;i<3;i++) { if(FD_ISSET(tab[i].sock,&fd)) morpion=traiterClient(tab[i].sock,morpion); } } }
Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
Mon espace perso[/B]
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]
Deja merci de m'avoir aidé, et je te remercie du temps que tu as pris pour moi.
désolé d'être lourd encore une fois, mais je comprends pas certaines de tes lignes...
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 typedef struct { int sock; char pseudo[100]; } Joueur; [...] int max = sock_ecoute; /* max sera le 1er argument de select (voir man) */ FD_SET(sock_ecoute, &fd); /* ajoute le ici sinon a chaque boucle du while tu le rajouteras */ Joueur tab[2]; while(1) { if(select(max+1,&fd,....) { perror("select"); exit(1); } if(FD_ISSET(sock_ecoute,&fd) { if(cpt_j < 2) { Joueur j; sock=accept(sock_ecoute,....); FD_SET(sock,&fd); j.sock = sock; //tu mets dans le champ, sock, la valeur de retour du accept tab[cpt_j] = j; // ALORS LA JE COMPRENDS PAS ! max = sock > max ? sock : max; morpion=traiterClient(sock,morpion); // ??? // Ma fonction traiterClient prends en argument un pseudo et le plateau de morpion // Alors que toi tu y mets la valeur de accept cpt_j++; } } else { int i = 0; for(i=0;i<3;i++) //Tu parcours la file d'attente { if(FD_ISSET(tab[i].sock,&fd)) //en essayant de voir quel client c'est manifesté morpion=traiterClient(tab[i].sock,morpion); //meme remarque que dans le if } } }
Ce que je veux dire c'est que tu ne fais apparaitre nul par le pseudo, et je vois pas trop pourquoi, tu as fait intervenir le tableau de structure tab[] !!!
Franchement, je suis desolé de t'embêter avec tous ça, mais ça me tiens vraiment à coeur de comprendre .
Peut-être une histoire de nuance entre "may" et "must" ? Enfin...si je propose ça, c'est peut-être parce-que j'ai trop lu de RFCs...Envoyé par Skyrunner
Un problème bien exposé
est, pour moitié, solutionné. / La connaissance s'accroît quand on la partage, pas quand on l'impose. / La violence est le langage des faibles.
Pour la fonction traiterClient j'ai repris exactement la même que dans le code que tu as posté plus haut et qui prenait en parametre sock et morpion.Envoyé par juve1897
Pour le pseudo du joueur, juste apres le accept tu n'a qu'a faire un recv (ou read) et mettre dans le champs pseudo de la structure ce que tu as recu via le recv. Encore faut-il que tu ais paramétré tes clients pour qu'ils envoient le pseudo après la connexion.
Petite erreur, remplace
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Joueur j; [...] j.sock = sock /* la je sauvegarde le socket du client qui est la valeur retournee par accept (man accept) et ca tu le sais */ tab[cpt_j] = j; /* je sauvegarde le joueur dans le tableau aucun debordement possible puisque la condition de ton if c'est cpt_j < 2 */
Par
Code : Sélectionner tout - Visualiser dans une fenêtre à part for(i=0;i<3;i++)
Ici je ne parcours pas la file d'attente, je parcours simplement mes différents joueurs (ici on en a 2) que j'ai ajouté un peu plus haut, et je regarde lequel a parlé c'est forcement l'un deux.
Code : Sélectionner tout - Visualiser dans une fenêtre à part for(i=0;i<2;i++)
Le tableau de structure represente tes 2 joueurs, dans chaque case se trouve un joueur.Ce que je veux dire c'est que tu ne fais apparaitre nul par le pseudo, et je vois pas trop pourquoi, tu as fait intervenir le tableau de structure tab[] !!!
Pourquoi ? Tout simplement c'est plus simple pour stocket à la fois le socket et le pseudo.
Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
Mon espace perso[/B]
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager