Bonjour à tous,
Je suis actuellement en train d'essayer de faire communiquer deux programmes entre eux en C grâce à une socket STREAM. Pour une raison qui m'échappe, et malgré toutes mes recherches, je n'arrive pas à résoudre la partie multiplexage.
Mon programme devrait se derouler ainsi : un duo connect - accept tout d'abord, la connexion étant faite, un recv et un send de chaque côté. Jusque là tout se passe comme il se doit.
Derrière je souhaite mettre en place un multiplexage sur la socket et sur l'entrée clavier (0) afin que d'un côté comme de l'autre ils puissent envoyer des messages tout en étant capable d'en recevoir. Or mon select sur la socket STREAM ne semble pas du tout vouloir recevoir de données (sur l'entrée clavier pas de soucis, mais les send() ne semblent pas provoquer le select de l'autre côté et donc la réception.
Voici le code associé (enfin le bout de code pour plus de légéreté, car le programme ne fait pas que ça, mais il s'agit ici d'une partie indépendante du programme) :
Celui qui déclenche le connect() le fait à travers cette fonction :
De l'autre côté, il y a multiplexage sur une socket d'ecoute 'sstreammoi', ce qui déclenche un accept et donc la création d'une socket 'sclt' - sclt = accept(...) - et j'aimerais lancer un nouveau multiplexage (dans un while(1) pour le moment mais ça changera plus tard pour la condition) sur sclt pour pouvoir des recv et send comme je le souhaite :
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 void envoyerDemande(int numClient, char *buffEnvoi){ // Socket int sstreamclient; struct sockaddr_in struct_sstreamclient; // Variables int n; char buffReception[MAXBUFF]; memset(buffReception, 0, MAXBUFF); fd_set conversation_readmask; // File descriptor sstreamclient = socket(AF_INET, SOCK_STREAM, 0); CHECK(sstreamclient, "Erreur de création socket"); // Détails de la socket cliente struct_sstreamclient.sin_family = AF_INET; struct_sstreamclient.sin_port = htons(listeClients.clients[numClient].port); struct_sstreamclient.sin_addr.s_addr = inet_addr(listeClients.clients[numClient].IP); bzero(struct_sstreamclient.sin_zero, 8); printf("\nDemande de connexion en cours, attente de la réponse\n"); printf("Infos client : %s:%d\n", listeClients.clients[numClient].IP, listeClients.clients[numClient].port); /** * Connexion au client */ // Envoi des informations de connexion CHECK (connect( sstreamclient, (struct sockaddr *)&struct_sstreamclient, sizeof(struct_sstreamclient)), "Erreur d'acceptation d'une connexion TCP\n"); //CHECK(send( sstreamclient, buffEnvoi, strlen(buffEnvoi), 0, (struct sockaddr *)&struct_sstreamclient, sizeof(struct_sstreamclient)), "Problème d'écriture\n"); CHECK(send(sstreamclient, buffEnvoi, strlen(buffEnvoi), 0), "Problème d'écriture\n"); // ACK memset(buffReception, 0, MAXBUFF); CHECK (recv(sstreamclient, buffReception, sizeof(buffReception), 0), "Problème de lecture\n" ); // Vérification printf("# %s\n", buffReception); // Attente de la réponse du client switch(verifRequeteRecu(buffReception)){ case 2 : // OUI printf("Reponse oui : %s\n", buffReception); /** * Conversation */ // system("clear"); printf("\n\n#######################################\n\n"); printf("Conversation avec %s : %s:%d\n", listeClients.clients[numClient].nom, listeClients.clients[numClient].IP, listeClients.clients[numClient].port); printf("Tapez '/quit' pour quitter la conversation\n"); printf("\n#######################################\n\n"); /** * Multiplexage */ FD_ZERO(&conversation_readmask); // Vide l'ensemble de lecture FD_SET(0, &conversation_readmask); // Clavier FD_SET(sstreamclient, &conversation_readmask); // Ecoute while(1){ /** * Conversation */ fflush(stdin); // Attente d'une entrée clavier ou de la réception sur la socket d'écoute FD_ZERO(&conversation_readmask); // Vide l'ensemble de lecture FD_SET(0, &conversation_readmask); // Clavier FD_SET(sstreamclient, &conversation_readmask); // Ecoute CHECK(n = select(4, &conversation_readmask, NULL, NULL, NULL), "Erreur de select\n"); if(n > 0 && FD_ISSET(sstreamclient, &conversation_readmask)){ /** * Reception sur la socket d'ecoute */ printf("RECEPTION CONVERSATION\n"); memset(buffReception, 0, MAXBUFF); CHECK (recv(sstreamclient, buffReception, sizeof(buffReception), 0), "Problème de lecture\n" ); printf("%s : %s\n", listeClients.clients[numClient].nom, buffReception); } else if(n > 0 && FD_ISSET(0, &conversation_readmask)){ /** * Entrée clavier */ //printf("EMISSION CONVERSATION\n"); // Choix memset(buffEnvoi, 0, MAXBUFF); printf(">> "); scanf("%s", buffEnvoi); printf("Vous : %s\n", buffEnvoi); //sprintf(buffEnvoi, "/CON#!#%s#!#%s#!#%d#!#\0", nomUtilisateur, getMonAdresseIp(), getMonPort(sstreammoi, struct_sstreammoi)); // user, IP, port CHECK(send(sstreamclient, buffEnvoi, strlen(buffEnvoi), 0), "Problème d'écriture\n"); printf("SEND\n"); } } break; case 3 : // NON printf("Reponse non : %s\n", buffReception); break; default : printf("Erreur reponse %d\n", verifRequeteRecu(buffReception)); break; } }
Avez-vous une idée du problème ?
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 // Attente d'une entrée clavier ou de la réception sur la socket d'écoute FD_ZERO(&readmask); // Vide l'ensemble de lecture FD_SET(0, &readmask); // Clavier FD_SET(sstreammoi, &readmask); // Ecoute CHECK(n = select(4, &readmask, NULL, NULL, NULL), "Erreur de select\n"); if(n > 0 && FD_ISSET(sstreammoi, &readmask)){ /** * Reception sur la socket d'ecoute */ lensstreammoi = sizeof(struct_sstreammoi); CHECK (sclt = accept( sstreammoi, (struct sockaddr *)&struct_sstreammoi, &lensstreammoi), "Erreur d'acceptation d'une connexion TCP\n"); memset(buffReception, 0, MAXBUFF); CHECK (recv(sclt, buffReception, sizeof(buffReception), 0), "Problème de lecture\n" ); printf("Message reçu : %s\n", buffReception); switch(verifRequeteRecu(buffReception)){ case 1 : // DEMANDE printf("Demande de la liste des connectes\n"); memset(buffEnvoi, 0, MAXBUFF); sprintf(buffEnvoi, "/LISTE#!#%s#!#%s#!#%d#!#\0", nomUtilisateur, getMonAdresseIp(), getMonPort(sstreammoi, struct_sstreammoi)); // user, IP, port recevoirListeClients(sdgramserveur, struct_sdgramserveur, buffEnvoi); // Necessaire de rafraichir la liste pour quel le nombre de clients soit à jour printf("L'utilisateur suivant :\n"); numClient = chercherUtilisateur(buffReception); printf("souhaite rentrer en contact avec vous. Accepter ? \n 1. Oui\n 2. Non\nEntrez votre sélection :\n"); scanf("%d", &choix); if(choix){ // Acceptation memset(buffEnvoi, 0, MAXBUFF); sprintf(buffEnvoi, "/YESDMD#!#%s#!#%s#!#%d#!#\0", nomUtilisateur, getMonAdresseIp(), getMonPort(sstreammoi, struct_sstreammoi)); // user, IP, port CHECK(send(sclt, buffEnvoi, strlen(buffEnvoi), 0), "Problème d'écriture\n"); CHECK(numClient, "Problème de numClient\n"); /** * Conversation */ // system("clear"); printf("\n\n#######################################\n\n"); printf("Conversation avec %s : %s:%d\n", listeClients.clients[numClient].nom, listeClients.clients[numClient].IP, listeClients.clients[numClient].port); printf("Tapez '/quit' pour quitter la conversation\n"); printf("\n#######################################\n\n"); /** * Multiplexage */ FD_ZERO(&conversation_readmask); // Vide l'ensemble de lecture FD_SET(0, &conversation_readmask); // Clavier FD_SET(sclt, &conversation_readmask); // Ecoute while(1){ /** * Conversation */ fflush(stdin); // Attente d'une entrée clavier ou de la réception sur la socket d'écoute FD_ZERO(&conversation_readmask); // Vide l'ensemble de lecture FD_SET(0, &conversation_readmask); // Clavier FD_SET(sclt, &conversation_readmask); // Ecoute CHECK(n = select(4, &conversation_readmask, NULL, NULL, NULL), "Erreur de select\n"); printf("n VAUT %d\n", n); if(n > 0 && FD_ISSET(sclt, &conversation_readmask)){ /** * Reception sur la socket d'ecoute */ printf("RECEPTION CONVERSATION\n"); memset(buffReception, 0, MAXBUFF); CHECK (recv(sclt, buffReception, sizeof(buffReception), 0), "Problème de lecture\n" ); printf("%s : %s\n", listeClients.clients[numClient].nom, buffReception); } else if(n > 0 && FD_ISSET(0, &conversation_readmask)){ /** * Entrée clavier */ printf("EMISSION CONVERSATION\n"); // Choix memset(buffEnvoi, 0, MAXBUFF); scanf("%s", buffEnvoi); printf("Vous : %s\n", buffEnvoi); //sprintf(buffEnvoi, "/CON#!#%s#!#%s#!#%d#!#\0", nomUtilisateur, getMonAdresseIp(), getMonPort(sstreammoi, struct_sstreammoi)); // user, IP, port CHECK(send(sclt, buffEnvoi, strlen(buffEnvoi), 0), "Problème d'écriture\n"); printf("SEND\n"); } } } else{ // Refus // Acceptation memset(buffEnvoi, 0, MAXBUFF); sprintf(buffEnvoi, "/NODMD#!#%s#!#%s#!#%d#!#\0", nomUtilisateur, getMonAdresseIp(), getMonPort(sstreammoi, struct_sstreammoi)); // user, IP, port CHECK(send(sclt, buffEnvoi, strlen(buffEnvoi), 0), "Problème d'écriture\n"); } break; default : printf("Erreur de requete"); break; } choix = -1; } (... suite des if sur le premier multiplexage)
Je vous remercie,
Partager