Rechercher : dans
Par :

[C] chat socket/fork/pipe

Dernière réponse le 26 mar 2008 à 17:31:42 cedricdd, le 8 mar 2007 à 02:27:24 
 Signaler ce message aux modérateurs

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);  
 
} 
Configuration: Windows XP
Firefox 2.0.0.2

Meilleures réponses pour « [C] chat socket/fork/pipe » dans :
Que fait un fork() ? Voir...ou le petit fork() illustré.... Introduction Lancement du père Le fork Maîtriser le fil d'exécution du père et celui du fils Les variables et les descripteurs de fichiers La synchronisation La fin Notes et...
Enlever ventirad socket A VoirProblème Je n'arrive pas à enlever le ventirad de mon processeur socket A. Solution Il y a un crochet sur un côté. Il faut appuyer avec le bout d'un tournevis plat, par exemple, sur le crochet pour le libérer. Merci à epango sur le forum...
Les fonctions de l'API Socket VoirLes fonctions des sockets en détail La fonction socket() La création d'un socket se fait grâce à la fonction socket() : int socket(famille,type,protocole) famille représente la famille de protocole utilisé (AF_INET pour TCP/IP utilisant une...

1

cedricdd, le 8 mar 2007 à 07:15:54

Voila j'ai mis en commentaire une partie du programme pour n'avoir qu'un client qui envoie un message avec le processus fils qui recoit le message et qui le transmet au père qui lui va juste le renvoier au fils qui va le renvoier au client, juste pour tester, y a pas de problème jusqu'a que le père renvoie le message, le premier message arrivera au client mais en même temps y a une boucle d'affichage du message dans le serveur qui se lance, et va occupé toute la memoire, je trouve pas de quoi ca provient

Répondre à cedricdd

2

noyau, le 12 mar 2007 à 22:20:17

Ben alors CDD, tu as des petits prob de C !!!!!
Utilise les listes chainées sa te fera du bien !!!!!

a demain ! ++

Répondre à noyau

3

Char Snipeur, le 13 mar 2007 à 08:46:41

Salut.
ça doit être un problème de libération de socket sur la boucle. Salutation !
Char Snipeur

Répondre à Char Snipeur

4

lina, le 17 mai 2007 à 22:10:56

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

Répondre à lina

5

Foo, le 3 oct 2007 à 09:09:45

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 :)

Répondre à Foo

6

 besla, le 26 mar 2008 à 17:31:42

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);

"

Répondre à besla