Bonjour,

Je voudrais créer sous la console un mini chat très simple.

Soit deux personnes A et B.
A peut recevoir et envoyer à B.
B peut recevoir et envoyer à A.

Je suis un peu perdu quant à la conceptualisation.

J'ai pour le moment fais le code permettant à A d'envoyer B et B de recevoir A. Le but est donc de permettre ceci dans les 2 sens.

SERVEUR
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/* Option projet : linkage librairie = libws2_32.a */
 
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#define PORT 80
#define BUFFER_SIZE 1025
 
int CompareChaine( char *s, char *t );
int LongueurChaine ( char *chaine );
int LireClavier( char *buffer, int longueur );
 
typedef int socklen_t;
 
 
 
int main(void)
{
    /* Configuration de la console */
    system("title APPLICATION SERVEUR");
    system("color F0                 ");
    system("MODE CON cols=75 lines=50 ");
 
    WSADATA WSAData;
 
    printf("\n CONSOLE :\n _________\n");
 
    /* Initialisation de la bibliothèque WinSock */
    int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
 
    /* Si erreur vaut 0, l'initialisation c'est bien passée et on continue. */
    if ( erreur == 0 )
       {
            printf("\n > INITIALISATION BIBLIOTHEQUE SOCKET REUSSIE");
            /* Déclaration des sockets serveur et client */
               /* Serveur */
               SOCKET socket_server ;
 
               /* Client  */
               SOCKET socket_client;
 
               printf("\n > DECLARATION SOCKET SERVEUR ET CLIENT");
 
            /* Déclaration des contextes d'adressages ( structure pour parametrer la socket )*/
               /* Serveur */
               SOCKADDR_IN client;
               socklen_t   client_t  = sizeof(client);
 
               /* Client  */
               SOCKADDR_IN server;
               socklen_t   server_t  = sizeof(server);
               printf("\n > DECLARATION CONTEXTE D'ADRESSAGE SOCKET SERVEUR ET CLIENT");
 
            /* Création de la socket serveur */
            socket_server = socket(AF_INET, SOCK_STREAM, 0);
 
            /* Si la socket a correctement été crée */
            if ( socket_server != INVALID_SOCKET )
               {
                   printf("\n > SOCKET SERVEUR CREE\n");
 
                   /* Alors paramètrage de la socket server : structure SOCKADDR_IN */
                   server.sin_addr.s_addr = htonl(INADDR_ANY);                          /* Adresse IP server       */
                   server.sin_family = AF_INET;                                         /* Protocole familial (IP) */
                   server.sin_port = htons(PORT);                                       /* Port d'écoute           */
 
                   printf("\n > INFORMATIONS SOCKET SERVEUR" );
                   printf("\n     NUMERO DE SOCKET  : %d", socket_server );
                   printf("\n     ADRESSE IP        : %s", inet_ntoa(server.sin_addr) );
                   printf("\n     PROTOCOLE UTILISE : TCP-IP"                        );
                   printf("\n     PORT D'ECOUTE     : %d\n", htons(server.sin_port)    );
 
                   /* Association du contexte d'adressage serveur au socket serveur */
                   int sock_err = bind(socket_server, (SOCKADDR*)&server, server_t);
 
                   /* Si l'association du contexte d'adressage serveur au socket serveur a reussie */
                   if ( sock_err != SOCKET_ERROR )
                      {
                          printf("\n > ASSOCIATION CONTEXTE D'ADRESSAGE SERVEUR - SOCKET SERVEUR REUSSIE");
 
                          /* Mise à l'écoute du serveur i.e attente de connexion(s) clients */
                          sock_err = listen(socket_server, 5);
 
                          /* Si la mise à l'écoute de la socket serveur a reussi */
                          if ( sock_err != SOCKET_ERROR )
                             {
                                 printf("\n > SERVEUR EN ATTENTE DE CONNEXIONS CLIENTS");
 
                                 /* On attend qu'un client se connecte au serveur */
                                 socket_client = accept(socket_server, (SOCKADDR*)&client, &client_t);
 
                                 printf("\n > CLIENT CONNECTE\n");
                                 printf("\n > INFORMATIONS SOCKET CLIENTS" );
                                 printf("\n     NUMERO DE SOCKET  : %d", socket_client );
                                 printf("\n     ADRESSE IP        : %s", inet_ntoa(client.sin_addr) );
                                 printf("\n     PROTOCOLE UTILISE : TCP-IP"                        );
                                 printf("\n     PORT SOURCE       : %d\n", htons(client.sin_port)    );
 
                                 /* Connexion établie : Envoie de messages au client */
 
                                 /* Buffer pour contenir la chaine à envoyer */
                                 char *buffer = (char *)malloc(BUFFER_SIZE*sizeof(char));
 
                                 /* Si l'allocation pour le buffer a réussie */
                                 if ( buffer != NULL )
                                    {
                                        printf("\n SESSION D'ENVOI DE MESSAGE\n __________________________\n\n");
                                        int continuer=1;
 
                                        /* Message de contrôle pour arrêter la saise de messages */
                                        char *arreter="quit";
 
                                        /* Tant que le serveur veut envoyer des messages au client */
                                        while ( continuer == 1 )
                                              {
                                                  printf(" > MESSAGE : ");
 
                                                  /* On demande de saisir le message à envoyer */
                                                  int saisie = LireClavier( buffer, BUFFER_SIZE );
 
                                                    /* Si la saisie es valide et que le serveur souhaite toujours envoyer des messages */
                                                    if ( (strcmp( buffer, arreter ) != 0) && (saisie == 1) )
                                                       {
                                                          sock_err = send( socket_client, buffer, BUFFER_SIZE, 0);
 
                                                          /* S'il y a eu une erreur de transmission sur le message, on le signale */
                                                          if ( sock_err == SOCKET_ERROR )
                                                             {
                                                                 printf(" > ERREUR DE TRANSMISSION\n");
                                                             }
                                                       }
 
                                                  /* Sinon on quitte la saisie de message */
                                                  else {
                                                           continuer = 0;
                                                       }
                                              }
 
                                        /* On arrête l'envoi de messages : on ferme alors la connexion */
                                        shutdown(socket_client, 2);
                                    }
                             }
 
                        /* Sinon l'on informe que la mise à l'écoute de la socket serveur a échoué */
                        else {
                                 perror("listen");
                             }
                      }
 
                /* Sinon l'on informe que l'association du contexte d'adressage au socket a echoué */
                 else {
                          perror("bind");
                      }
 
 
                   /* Fermeture de la socket client et de la socket serveur */
                   closesocket(socket_client );
                   closesocket(socket_server);
                   printf("\n > FERMETURE DES SOCKETS CLIENT ET SERVEUR REUSSIE\n\n");
 
               }
 
          /* Sinon on informe qu'il y a eu une erreur lors de la création de la socket */
          else {
                   perror("socket");
               }
       }
 
  /* Sinon on quitte le programme */
  else {
           /* Libérations des ressources utiliées par la fonction WSAStartup */
           WSACleanup();
           printf("\n\n ERREUR : L'initialiation de la bibliothèque winsock2.h a echouee\n\n");
           return EXIT_FAILURE;
       }
 
   /* Libérations des ressources utiliées par la fonction WSAStartup */
   WSACleanup();
   system("pause");
   return EXIT_SUCCESS;
}
 
int LireClavier( char *buffer, int longueur )
{
     /* */
     if ( buffer != NULL )
        {
            /* Si la saisie a reussie */
            if ( fgets( buffer, longueur, stdin ) != NULL )
               {
                   /* On supprime le possible retour chariot */
                   while ( *buffer != '\0' )
                         {
                             if ( *buffer == '\n' )
                                {
                                    *buffer = '\0';
                                }
 
                             buffer++;
                         }
 
                   /* On retourne 1 : la saisie a correctement été traité */
                   /* On vide stdin en cas d'overflow du buffer */
                   fflush(stdin);
                   return 1;
               }
 
          /* Si erreur on retourne 0 */
          else {
                   return 0;
               }
        }
   /* Si erreur, on retourne -1 */
   else {
            return -1;
        }
}
CLIENT
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
/* Option projet : linkage librairie = libws2_32.a */
 
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#define PORT 80
#define BUFFER_SIZE 1025
 
typedef int socklen_t;
 
int main(void)
{
    /* Configuration de la console */
    system("title APPLICATION CLIENT");
    system("color F0                 ");
    system("MODE CON cols=75 lines=50 ");
 
    WSADATA WSAData;
 
    printf("\n CONSOLE :\n _________\n");
 
    /* Initialisation de la bibliothèque WinSock */
    int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
 
    /* Si l'initialisation a réussie */
    if ( erreur == 0)
       {
           printf("\n > INITIALISATION BIBLIOTHEQUE SOCKET REUSSIE");
 
           /* Création de la socket serveur */
           SOCKET socket_server = socket(AF_INET, SOCK_STREAM, 0);
 
           /* Si la socket a correctement été crée */
           if ( socket_server != INVALID_SOCKET )
              {
                  printf("\n > SOCKET DE CONNECTION AU SERVEUR CREE");
 
                  /* Declaration du contexte d'adressage du client pour la socket client */
                  SOCKADDR_IN server;
 
                  /* Alors on configure son contexte d'adressage sin */
                  server.sin_addr.s_addr = inet_addr("127.0.0.1");     /* Adresse IP */
                  server.sin_family = AF_INET;                         /* Famille IP */
                  server.sin_port = htons(PORT);                       /* Port       */
 
                  printf("\n > INFORMATIONS DU SERVEUR A CONTACTER ENTREES\n");
 
                  /* Si le client arrive à se connecter */
                  int tentative = 0;
                  while ( connect(socket_server, (SOCKADDR*)&server, sizeof(server)) == SOCKET_ERROR)
                        {
                             printf("\n > TENTATIVE NUMERO %d DE CONNEXION DU CLIENT AU SERVEUR", tentative);
                             tentative++;
                        }
 
                  printf("\n > CONNEXION REUSSIE\n\n");
 
                  printf("\n\n SESSION D'ENVOI DE MESSAGE\n __________________________\n\n");
 
                  /* Buffer pour recevoir les données venant du serveur */
                  char *buffer = (char *)malloc(BUFFER_SIZE*sizeof(char));
 
                  if ( buffer != NULL )
                     {
 
                         /* Tant qu'on reçoit des messages et qu'il n'y a pas d'erreur, on les affiches */
                         while ( recv(socket_server, buffer, BUFFER_SIZE, 0 ) != SOCKET_ERROR )
                               {
                                    printf("> MESSAGE RECU : %s\n", buffer);
                               }
 
                        /* Sinon on prévient qu'une erreur est survenue */
                        printf("\n ERREUR DE TRANSMISSION");
                     }
 
                   /* On ferme la socket serveur précédemment ouverte */
                  closesocket(socket_server);
              }
 
         else {
                  perror("socket");
              }
       }
 
  /* Sinon on quitte le programme*/
  else {
           /* Libérations des ressources utiliées par la fonction WSAStartup */
           WSACleanup();
           system("pause");
           return EXIT_SUCCESS;
       }
 
    /* Libérations des ressources utiliées par la fonction WSAStartup */
    WSACleanup();
    system("pause");
    return EXIT_SUCCESS;
}
Le but final serait que puissent se connecter X chatters.
J'aurais aimé savoir avec votre expérience quelle serait la manière la plus simple de réaliser ceci.

il y aurait en fait 1 personne qui serait à la fois serveur et client ( permet aux autres de se connecter et lui même de participer à la conversation ) et X-1 autres qui seraient donc clients et se connecteraient sur le serveur.

Donc 2 applications séparées. L'une qui ferait serveur/client et l'autre uniquement client.

D'un point de vue socket, je ne sais pas comment calibrer mon réseau pour que les communications soient possibles.

C'est un projet de cours, en fait je dois recréer le jeu blokus avec une partie réseau à 4 joueurs fonctionnel en local ou sur le net.

Je n'ai pas eu de cours et je me suis inspiré du tutoriel C donné par le site .

Dans un premier temps, j'aimerais avant de passer aux choses sérieuses réaliser sous console ce mini chat ou chacune des personnes reçoivent les messages des uns des autres.

Je ne sais pas vraiment comment m'y prendre dans le principe. Dans le réseau, comment est configuré chaque client et le client/serveur ( ip/port.. )

Donc si aviez quelques conseils ou explications pour m'aider dans la compréhension des communications dans un tel schéma, ce serait fort bien aimable.

Je sais que j'aurais également besoin d'utiliser les threads à cause des fonctions blocantes pour permettre à la fois l'envoi et l'acquisition de message. Je me suis lancé dans la bibliothèque pthread expliqué également dans le tutoriel allant avec winsock2.h. Est ce une bonne idée ? car par exemple si j'ai bien compris la fonction pthread_create qui permet de lancer une tâche en parallèle, ne prends que des fonctions du type void *mafonction(void *data) ce qui est loin d'être le prototype de la fonction recevoir par exemple alors je ne vois pas comment m'en sortir. D'autant plus qu'on ne peut traiter qu'un argument de type void*. Je suis un peu perdu et confu.

Merci d'avance pour vos éclaircissements

Voici pour le moment ce que j'ai codé.