Création
d'entreprise
Posez votre question Signaler

[C] chat socket/fork/pipe [Résolu]

cedricdd 3Messages postés 8 mars 2007Date d'inscription 12 juin 2010Dernière intervention - Dernière réponse le 26 mars 2008 à 17:31
Voila j'ai comme projet de réaliser un chat en C,en utilisant les sockets, fork et des pipes, mais j'ai des erreurs dans mon serveur, pourtant je ne vois pas ou j'ai faux
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#define maxclient 10
 
 
typedef struct{
 int envoie[2];
 int recep[2];
 int libre;
}t_fils;
       
int main()
 
{
 system("clear" );
 printf("Lancement du serveur\n\n" );
 
 t_fils tabFils[maxclient];
 int i=0,nbrclient=0,client=0,traite=1,test,test2,sock,sock2,duplication,placeclient=0,clientok=0,placeclientenvoie;
 int sizet= sizeof(struct sockaddr);
 struct sockaddr_in sin,csin;
 char bufferR[1024]="",bufferE[1024]="",buffer[1024]="",temp[10]="";
       
 if ( (sock=socket ( AF_INET, SOCK_STREAM, 6)) == -1)
 {
  printf("Socket creation erreur" );
 }
 
   
 memset ( &sin, 0, sizeof(struct sockaddr));
 memset ( &csin, 0, sizeof(struct sockaddr));
 
 sin.sin_family= AF_INET;
 sin.sin_port=htons( 6222);    
 sin.sin_addr.s_addr=htonl(INADDR_ANY);
 
 
 if ( bind( sock,(struct sockaddr *)&sin, sizeof(struct sockaddr) ) == -1 )
 {
  printf("Impossible lier socket" );
 }
 else
 {        
  printf("Serveur ok, en attente de client, nombre maximun de client %i\n\n",maxclient);
 }  
 
 listen(sock, 1);
 
 for(i=0;i<maxclient;i++)
  {
   tabFils[i].libre=0;
  }
 
   
 fcntl(sock, F_SETFL, fcntl ( sock, F_GETFL ) | O_NONBLOCK);
 
 while(nbrclient<10)  //Boucle plusieurs clients
 {
 
 
  client=0;
   
   
   
   
     if( (sock2 = accept(sock ,(struct sockaddr *)&csin, (socklen_t *)&sizet ) ) == -1 )
  {
   //printf("Impossible d'accepter" );
  }
      else  
  {
   printf("\nCLIENT ENTRANT\n\n" );
   client=1;
  }
   
   
  if ( client == 1)
  {
   nbrclient+=1; //Un nouveau client
   
 
   do //Le nouveau client prendra la premiere place libre
   {
    if(tabFils[placeclient].libre == 0) //La place est libre
    {
     if (  pipe(tabFils[placeclient].recep) == -1 || pipe(tabFils[placeclient].envoie) == -1 )  //Pour communiquer entre le pere et le fils
     {
      printf("Erreur lors de la déclaration des tubes" );
     }
     clientok=1;
    }
    else //Un client occupe déjà cette place
    {
     placeclient++;
    }
   }while(clientok !=1); //Le client à trouvé une place
 
 
   duplication=fork();
 
   if( duplication == -1)
   {
    printf("Erreur dans la duplication du processus" );
    exit(0);
   }
 
   if( duplication !=0)  //Processus pere
   {
    close(sock2);
    close(tabFils[placeclient].envoie[0]);
    close(tabFils[placeclient].recep[1]);
    fcntl(tabFils[placeclient].recep[0], F_SETFL, fcntl (tabFils[placeclient].recep[0], F_GETFL ) | O_NONBLOCK);
    tabFils[placeclient].libre=1;
   }
 
   else // Processus fils
   {
 
    close(tabFils[placeclient].envoie[1]);
    close(tabFils[placeclient].recep[0]);
 
    fcntl(sock2, F_SETFL, fcntl ( sock2, F_GETFL ) | O_NONBLOCK);
    fcntl(tabFils[placeclient].envoie[0], F_SETFL, fcntl (tabFils[placeclient].envoie[0],  F_GETFL ) | O_NONBLOCK);
     
 
    while(1)
    {
           
       
     memset(bufferR, 0, sizeof(bufferR));
     memset(buffer, 0, sizeof(buffer));
     
     if ( read(sock2, bufferR, 255) > 0 )
     {
      if ( strlen( bufferR ) !=0) //Pour eviter les messages fantomes
      {
       strncpy(temp, bufferR, 4);
       
       if( strcmp( temp, "exit" ) == 0 )
       {
        write(tabFils[placeclient].recep[1], temp, sizeof(temp));
        close(tabFils[placeclient].envoie[0]);
        close(tabFils[placeclient].recep[1]);
       }
       else
       {
       
        write(tabFils[placeclient].recep[1], bufferR, sizeof(bufferR));
       
       }
      }      
     }
 
 
     memset(bufferE, 0, sizeof(bufferE));
     if ( read (tabFils[placeclient].envoie[0],  bufferE, 1024) > 0 )
     {
      if ( strlen ( bufferE ) != 0 )
      {
       write(sock2, bufferE, sizeof(bufferE));
       printf("J'envoie au client %s",bufferE);
      }
     }
 
    }  
 
   }   //Fin du fils
 
   
 
  }
         //Traitement dans le père
     
    for(test=0;test<nbrclient;test++)
    {
     if( read( tabFils[test].recep[0], bufferR, 1024) > 0)
     {
      if( strlen ( bufferR) !=0 )
      {
       
 
       placeclientenvoie=test;
     
       strncpy(temp, bufferR, 4);
       if( strcmp( temp, "exit" ) == 0 )
       {
        printf("Un client vient de partir, il en reste %i\n",nbrclient-1);
        traite=0;
        nbrclient--;
        tabFils[test].libre=0;
       }
 
 
       if ( traite == 1) //Si se n'est un message de deconnection
       {
        printf("le pere affiche:  %s\n",bufferR);
        if( nbrclient==1)
        {
         write(tabFils[0].envoie[1], "Vous êtes le seul client\r\n", sizeof("Vous êtes le seul client\r\n" ));
        }
 
        else
        {
         for(test2=0;test<nbrclient;test2++)
         {
          if(placeclientenvoie != test2) //On ne renvoie pas a celui qui vient d'écrire
          {
           write(tabFils[test2].envoie[1], bufferR, sizeof(bufferR));
          }
         }
        }
       }
       
       else //De base on retraite le suivant
       {
        traite=1;
       }
      }
     }
    }
     
 
         
 
 }    //Fin boucle plusieurs clients
 
 
close(sock);
close(sock2);  
 
} 
Lire la suite 

[C] chat socket/fork/pipe »

5 réponses
Réponse
+0
moins plus
Bonjour,
"
salut cedric, g exactement le même projet ke toi a realiser, pourrais-tu m'envoyer le tien afin ke je puisse ajouter des ameliorations sur le mien ou voir ce que je pourrais modifier... please.
je te laisse mon adresse: kaliyah78@hotmail.fr
"

j'adore :)
Ajouter un commentaire
Réponse
+0
moins plus
bonjour,

est ce que tu peux m expliquer un peut ce que tu fais avec fcntl parce que je vois pas trop ce que tu veux faire avec !
"
fcntl(sock2, F_SETFL, fcntl ( sock2, F_GETFL ) | O_NONBLOCK);
fcntl(tabFils[placeclient].envoie[0], F_SETFL, fcntl (tabFils[placeclient].envoie[0], F_GETFL ) | O_NONBLOCK);

"
Ajouter un commentaire
Réponse
-1
moins plus
Ben alors CDD, tu as des petits prob de C !!!!!
Utilise les listes chainées sa te fera du bien !!!!!

a demain ! ++
Ajouter un commentaire
Réponse
-1
moins plus
Salut.
ça doit être un problème de libération de socket sur la boucle.
Ajouter un commentaire
Réponse
-1
moins plus
salut cedric, g exactement le même projet ke toi a realiser, pourrais-tu m'envoyer le tien afin ke je puisse ajouter des ameliorations sur le mien ou voir ce que je pourrais modifier... please.
je te laisse mon adresse: kaliyah78@hotmail.fr
merci
Ajouter un commentaire
Ce document intitulé « [C] chat socket/fork/pipe » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Dossier à la une
Passage au tout numérique : quel coût pour les particuliers ?