Application de chat

Fermé
haikei00X Messages postés 67 Date d'inscription dimanche 20 juillet 2014 Statut Membre Dernière intervention 11 janvier 2016 - 20 août 2015 à 16:16
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 - 7 sept. 2015 à 19:32
Bonjour tout le monde. Je travaille sur une application de chat et je suis débutante dans le monde des sockets et des protocoles de connexion. Je bloque depuis des jours sur un truc, et je commence déjà à stresser car je doit rendre le projet dans un délai de 10 jours.
Mon problème est le suivant:
A la connexion d'un client, le serveur doit envoyer la liste des clients connectés identifiés par leur adresse Ip. J'ai écrit le code mais je n'obtiens pas le résultat souhaité.A chaque fois qu'un client se connecte, on ne m'affiche qu'une seule adresse. Je sais que j'ai un problème au niveau du send() et du recv(). Je vous met mon code serveur et mon code client.
Server:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

//Structure informations client
  struct ClientInfos{
  char Ip[10] ;
  int pid;
  }; 
 //Tableau de structures où on stocke les infos sur l'ensemble des clients connectés 
  struct ClientInfos clients[3] ;

//Structure  de conversation
struct conv{
char msg[99] ;//Useful for the conversations storage
char IpAdd[10] ;//So the client knows who is talking to him
};

int i = 0 ;

int main(){

    
        printf("The server is runing .... \n");
	int servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(servSock <0){
		printf("Socket Creation Error \n");	
	}else{
		printf("Socket Created ... \n");	
	}
	struct sockaddr_in servAddr;
	memset(&servAddr,0,sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servAddr.sin_port = htons(1214);
	
	if(bind(servSock, (struct sockaddr*) &servAddr, sizeof(servAddr))<0){
		printf("Error while bind fonction is called");
		exit(0);
	}	
	printf("Successful bind ... \n");	

	printf("before Listening ... \n");
	listen(servSock, 4);
	printf("Listening ...\n");
		
  while(1){
	printf("waiting for a client ... \n");
	struct sockaddr_in clntAddr;
	socklen_t clnAddrLen = sizeof(clntAddr);
	int clntSock = accept(servSock, (struct sockaddr*) &clntAddr, &clnAddrLen);
	if(clntSock <0)
	  printf("Accept failed");

	printf("A client has been connected ... \n");
	//send(clntSock,"Successful connect",99,0) ;
	
        
	int pid = fork() ;
   // the communication with the clients
   if(pid == 0){
	
     //Saving client infos
	clients[i].pid = getpid() ;	
	strcpy(clients[i].Ip,inet_ntoa(clntAddr.sin_addr)) ;
        send(clntSock,clients[i].Ip,90,0);
	i++ ;

     exit(0) ;
		
 

    }
			  
  }
    return  0 ;
}



Client:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>

//Structure informations client
struct ClientInfos{
int pid ;
char Ip[10] ;  
};
//Tableau de structures où on stocke les infos sur l'ensemble des clients connectés
struct ClientInfos clients[3] ;

int i = 0 ;

int main(){
	printf("The Client is runing .... \n");
	int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(sock <0){
		printf("Socket Creation Error \n");	
	}else{
		printf("Socket Created ... \n");	
	}
	struct sockaddr_in servAddr;
	memset(&servAddr,0,sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	servAddr.sin_port = htons(1214);
	
	connect(sock, (struct sockaddr *) &servAddr, sizeof(servAddr));
	printf("Successful connect ... \n");

       printf("Connexion to the server 127.0.0.1::1214...\n") ;	

       printf("Connected clients list : \n") ;

	while(1){
	
        recv(sock, clients[i].Ip, 99, 0);
	int j ;

        for(j=0;i<3;i++){
        if(strcmp(clients[j].Ip," ")!= 0){
	 printf("%s \n", clients[j].Ip);
         i++ ;
        }
        else
         break ;
       }
	close(sock) ;


	}
        return 0 ;
	
}

1 réponse

chris79 Messages postés 91 Date d'inscription lundi 3 octobre 2005 Statut Membre Dernière intervention 1 février 2016 25
2 sept. 2015 à 01:06
Salut,

Ton problème est lié au fait que ton tableau clients est mis à jour par le fils que tu crées pour gérer la communication sur le serveur.
Le fork copie les données du père mais elles ne sont pas partagées.

Il faut faire la mise à jour avant le fork pour arranger ça.

++
0
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
7 sept. 2015 à 19:32
Bonjour
D'un autre côté la structure définie ne sert pas à grand-chose et pourquoi diable vous faut-il sauvegarder le PID ?
Le mieux est de sauvegarder l'adresse dans un tableau qui correspond à l'ensemble des clients qui sont connectés et gérés celui-ci en fonction des clients online. Si pas de client son adresse est retirée du tableau cas contraire il y est toujours présent et il suffit par la suite de crée une chaine contenant l'ensemble des adresses et l'envoyer au client pour savoir qui est connecté.
Le code écrit est incomplet à mon sens donc qui dit FORK dit gestion des zombies et il est préférable également de rendre le serveur non bloquant.
à bientôt
0