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 :
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;
      }
}
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
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)
Avez-vous une idée du problème ?

Je vous remercie,