Bonjour, je me suis récemment lancé dans la programmation TCP et j'essaie de construire une petite messagerie instantanée.Un serveur, des clients liés 2 par 2. Mais jusque là avec ce code je n'arrive qu'à communiquer entre serveur et clients. Je coince au niveau de la communication client client. Comment envoyer le buffer d'une socket liant le client et le serveur à une autre socket liant le serveur et un autre client ?
Code C du 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
// en-tetes C standards
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// en-tete unix:
#include <unistd.h>
// en-tetes reseaux:
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define BUFFER_SIZE 1024
// déclaration de variables
int clients=0;
int tabClients[][]=0;
int cree_socket_tcp_ip();
int affiche_adresse_socket(int sock);
int affiche_adresse_distante(int sock);
int connexion(int socket_contact);
void traitement( int socket );
int main() {
	printf("Bonjour!\n");
	int socket_contact;
	int socket_connectee;
	pid_t pid;
	// creation socket de contact:
	socket_contact = cree_socket_tcp_ip();
	// affichage adresse locale:
	affiche_adresse_socket( socket_contact );
	//  ecoute sur le port. Jusqu'à 6 requêtes possibles:
	listen( socket_contact, 6 );
	while (1) {
		socket_connectee = connexion( socket_contact );
		pid = fork();
		if (pid==-1) {
			perror( "fork" );
			close( socket_contact );
			close( socket_connectee );
			exit(1);
		}
		else if (pid==0) {
			// fils -> on continue avec la socket connectée:
			close(socket_contact);
			// affichage machine distante:
			affiche_adresse_distante( socket_connectee );
			// communication:
			traitement( socket_connectee );
			close(socket_connectee);
			exit(0);
		}
		else {
			// père -> traiter la requ`ete suivante:
			close(socket_connectee);
		}
	}
	close(socket_contact);
	printf("Au revoir!\n");
}
int connexion(int socket_contact) {
	struct sockaddr_in adresse;
	int socket_connectee;
	socklen_t longueur;
	socket_connectee = accept(socket_contact,(struct sockaddr*)&adresse,&longueur);
		if (socket_connectee < 0){
			perror( "accept" );
			close(socket_contact);
			exit(11);
		}
		else{
			printf("Creation socket client \n");
			clients+=1;
			printf("Nombre de clients: %d\n", clients);
			/*if (clients%2 ==0){
				cree_socket_tcp_ip();
			}*/
            close(socket_contact);
	}
return socket_connectee;
}
void traitement( int socket_connectee ) {
	char buffer[BUFFER_SIZE];
	int nb;
	// envoi du message d'accueil:
	strcpy( buffer, "Bienvenue sur le serveur. Ecrivez quelque chose...(exit pour sortir) " );
	write( socket_connectee, buffer, strlen(buffer)+1 );
	// reception des reponses de la machine distante:
	while (1) {
		nb = read(socket_connectee, buffer, BUFFER_SIZE);
		// rupture de la connexion par le client:
		if ( nb == 0)
			break;
			buffer[nb-1] = '\0';
			// affichage:
			printf( "Client: %s\n", buffer );
			// sortie demandée
			if ( !strcmp( buffer, "exit" ) )
				break;
	}
}
int cree_socket_tcp_ip(){
	int sock;
	struct sockaddr_in adresse;
	// IP et TCP:
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		fprintf(stderr, "Erreur socket.\n");
		exit(1);
	}
	memset(&adresse, 0, sizeof(struct sockaddr_in));
	adresse.sin_family = AF_INET;  // Protocol IP
	adresse.sin_port = htons(33016);  // port 33016
	inet_aton("127.0.0.1", &adresse.sin_addr); // IP localhost
	if (bind(sock, (struct sockaddr*) &adresse, sizeof(struct sockaddr_in)) < 0){
		close(sock);
		perror("Erreur bind");
		exit(2);
	}
return sock;
}
int affiche_adresse_socket(int sock){
	struct sockaddr_in adresse;
	socklen_t longueur;
	longueur = sizeof(struct sockaddr_in);
	if (getsockname(sock, (struct sockaddr*)&adresse, &longueur) < 0){
		close(sock);
		perror("Erreur getsockname");
		exit(3);
	}
	printf("IP = %s, Port = %u\n", inet_ntoa(adresse.sin_addr), ntohs(adresse.sin_port));
return 0;
}
int affiche_adresse_distante(int sock){
	struct sockaddr_in adresse;
	socklen_t longueur;
	char buffer[BUFFER_SIZE];
	longueur = sizeof(struct sockaddr_in);
	if (getpeername(sock, (struct sockaddr*) &adresse, &longueur) < 0) {
		perror( "getpeername" );
		close(sock);
		exit(12);
	}
	printf( "Client d'adresse IP = %s, sur le port = %u\n", inet_ntoa(adresse.sin_addr), ntohs(adresse.sin_port) );
return 0;
 
}
Je pensais créer un tableau de clients, enregistrer leurs informations et trouver un moyen de couper la connexion par multiple de 2 utilisateurs.

Code C du 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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 1024
 
int cree_socket_tcp_ip_client();
int affiche_adresse_socket(int sock);
void communication( int socket );
int main(int argc, char *argv[] ) {
	printf("Bonjour!\n");
	int port;
	int socket;
	if ( argc!= 3 ) {
		printf("usage: connect num_IP num_port.\n");
		exit(1);
	}
	else
		// conversion chaine de caractere -> nombre entier:
		sscanf( argv[2], "%d", &port );
		// création socket de connexion:
		socket = cree_socket_tcp_ip_client( argv[1], port );
		affiche_adresse_socket( socket );
		communication( socket );
		close( socket );
		printf("Au revoir!\n");
	}
	void communication( int socket ) {
		char buffer[BUFFER_SIZE];
		int nb;
		// réception du message d'accueil:
		nb= read(socket, buffer, BUFFER_SIZE);
		buffer[nb-2] = '\0';
		// affichage:
		printf( "%s\n", buffer );
		// envoi des r ?eponses:
		while(1) {
			fgets( buffer, BUFFER_SIZE, stdin );
			write( socket, buffer, strlen(buffer) );
			if ( !strcmp( buffer, "exit" ) )
				break;
		}
	}
	int cree_socket_tcp_ip_client( char *ip, int port )
	{
	int socket_contact;
	struct sockaddr_in adresse;
	// IP et TCP:
	if ((socket_contact = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("Erreur socket");
		exit(1);
	}
	// initialisation `a 0 puis affectation des champs:
	memset(&adresse, 0, sizeof(struct sockaddr_in));
	adresse.sin_family = AF_INET;  // Protocol IP
	adresse.sin_port = htons(port);  // port 33016
	inet_aton(ip, &adresse.sin_addr); // IP internet
	// connexion au site local:
	if (connect(socket_contact, (struct sockaddr*) &adresse, sizeof(struct sockaddr_in)) < 0){
		close(socket_contact);
		perror("Erreur connect");
		exit(2);
	}
	return socket_contact;
	}
int affiche_adresse_socket(int sock)
{
	struct sockaddr_in adresse;
	socklen_t longueur;
	longueur = sizeof(struct sockaddr_in);
	if (getsockname(sock, (struct sockaddr*)&adresse, &longueur) < 0){
		close(sock);
		perror("Erreur getsockname");
		exit(3);
	}
	printf("IP = %s, Port = %u\n", inet_ntoa(adresse.sin_addr), ntohs(adresse.sin_port));
return 0;
}
J'ai voulu aussi créer une socket liant directement les clients mais je me suis dit que ça ne servait plus à rien d'avoir un serveur, à moins que je puisse créer cette socket depuis le programme serveur (chose que je ne sais pas faire).