IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

Linux - problème avec fifos (communication IPC)


Sujet :

Linux

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Linux - problème avec fifos (communication IPC)
    Bonjour, je vous explique mon problème. Je dois réaliser un jeu de bataille navale en utilisant la communication inter proccessus (basé sur un serveur et 2 clients). Pour celà, j'utilise des fifos (via mkfifo()). Tout se passe bien lors de l'exécution du serveur. Le problème survient lors de l'exécution des clients, plus particulièrement pour le client 2 au niveau du changement de fifo (car client 1 ne communique pas sur le même canal que . En effet ceux-ci ne fonctionnent pas correctement lors du changement de fifo (car il faut que les clients communiquent via des canaux différent).
    Ce qui est bizarre c'est que la procédure de changement de fifo me semble correcte. Lorsque celle çi est mise en commenctaire ça fonctionne.

    pour infos, j'ai développé sous fedora.
    Je vous montre le code ci dessous. C'est très répétitif je sais, je dois mettre en fct mais je voudrais d'abord que le début fonctionne.

    voici le code 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
     
    int main(){
    int numclient;
    char reponse[1];
     
    /* creetab(&tableau);
    affichetab(&tableau);
    placerboat(&tableau);
    */
    //connection vers serveur
    int canalaller= open("client1",2);
    int canalretour= open("serveur1",2);
     
    if ((canalaller==-1) && (canalretour==-1)){
    printf("\nConnection au serveur impossible.\nAppuyer sur enter pour quitter");
    getchar();
    exit(1);
    }
     
    //envoi de la demande de connection
    printf("demande conn= %d",write(canalaller,"A",1));
     
    //réception d'un # de client
    printf("recep num= %d",read(canalretour,reponse,1));
    printf("reponse=%c",reponse);
    numclient=atoi(reponse);
    printf("\nVous etes le joueur= %d",numclient);
     
    //changement de fifos
    if (numclient==1){
    //pas de changement
    }
    else if (numclient==2){
    puts("Changement de fifo");
    close(canalaller);
    close(canalretour);
     
    canalaller=open("client2",2); //ouverture
    canalretour=open("serveur2",2);
     
    if ((canalaller==-1) && (canalretour==-1)){
    printf("\nConnection au serveur impossible.\nAppuyer sur enter pour quitter");
    getchar();
    exit(1);
    }
    puts("1");
    }
     
    //attente du depart de serveur
    read(canalretour,reponse,1);
    printf("\nreponse= %c",reponse);
    if (reponse!="Z") puts("\nServeur pas pret, veuillez recommencer");
    /*
    //encodage de la grille
    puts("\nEncoder votre grille");
    getchar();
    //*******************
    int i,j;
    for (i=0; i<11; i++){
    for (j=0; j<11; j++){
    tableau[i][j]="A";
    }
    }
     
    //envoi de la grille
    write(canalaller,tableau,121);
    read(canalretour,reponse,2); //ack
    printf("\nackCL1: %c ",reponse);
    puts("\nLa grille a bien été envoyee");
    getchar();*/
    }
    voici le code 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
     
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<fcntl.h>
     
    int main(){
    char tmp, tmp2;
    char suppr_serveur1[20+1]="rm -f serveur1";
    char suppr_serveur2[20+1]="rm -f serveur2";
    char suppr_client1[20+1]="rm -f client1";
    char suppr_client2[20+1]="rm -f client2";
    char grilleclients[2][11][11];
    int ok=0;
     
    //suppression des anciens fifos
    //LA SUPPRESSION SE FAIT D'OFFICE
    system(suppr_serveur1);
    system(suppr_serveur2);
    system(suppr_client1);
    system(suppr_client2);
     
    //Creation et ouverture du premier canal de communication
    int A = mkfifo("serveur1", 0666);
    if (A==-1) {
    puts("\nProbleme de création de canal de communication");
    puts("Appuyer sur enter pour quitter");
    getchar();
    exit(-1);
    }
    int canal1aller = open("serveur1",2);
    if (canal1aller==-1) {
    puts("\nProbleme d'ouverture du canal de communication");
    puts("Appuyer sur enter pour quitter");
    getchar();
    exit(-1);
    }
     
    int C=mkfifo("client1", 0666);
    if (C==-1) {
    printf("\nC=%d",C);
    puts("\nProbleme de création du canal de communication");
    puts("Appuyer sur enter pour quitter");
    getchar();
    exit(-1);
    }
    int canal1retour=open("client1",2);
    if (canal1retour==-1){
    puts("\nProbleme d'ouverture du canal de communication");
    puts("Appuyer sur enter pour quitter");
    getchar();
    exit(-1);
    }
     
    system("clear");
    puts("Serveur pret.\nAttente du PREMIER joueur.");
     
    //test présence joueur 1 + envoi num client
    read(canal1retour, &tmp, 1);
    if (tmp=='A') {
    printf("\tClient 1 connecte.");
    ok=1;
    }
    else {
    puts("\nProbleme de connection avec premier joueur");
    puts("Appuyer sur enter pour quitter");
    getchar();
    exit(-1);
    }
    write(canal1aller,"1",1); //client 1
    puts("\nAttente du SECOND joueur.");
     
    //test présence joueur 2 + envoi num client
    read(canal1retour, &tmp2, 1);
    if (tmp2=='A') {
    printf("\tClient 2 connecte.");
    ok=1;
    }
    else {
    puts("\nProbleme de connection avec second joueur");
    puts("Appuyer sur enter pour quitter");
    getchar();
    exit(-1);
    }
     
    write(canal1aller,"2",1); //client 2
     
    //ouverture du second canal de communication
    puts("\nTentative de creation et d'ouverture du second canal de communication");
     
    int B = mkfifo("serveur2", 0666);
    if (B==-1) {
    puts("\nProbleme de création du canal de communication");
    puts("Appuyer sur enter pour quitter");
    getchar();
    exit(-1);
    }
    int canal2aller = open("serveur2",2);
    if (canal2aller==-1) {
    puts("\nProbleme d'ouverture du canal de communication");
    puts("Appuyer sur enter pour quitter");
    getchar();
    exit(-1);
    }
     
    int D=mkfifo("client2", 0666);
    if (D==-1) {
    printf("\nclient2=%d",D);
    puts("\nProbleme de création du canal de communication");
    puts("Appuyer sur enter pour quitter");
    getchar();
    exit(-1);
    }
    int canal2retour=open("client2",2);
    if (canal2retour==-1) {
    puts("\nProbleme d'ouverture du canal de communication");
    puts("Appuyer sur enter pour quitter");
    getchar();
    exit(-1);
    }
     
    puts("\nLes deux canaux de communications sont etablis.");
    puts("Les joueurs procedent à l'encodage de leur grille");
     
    /*
    canal1aller = serveur1: pour envoyer ou client1
    canal2aller = serveur2: pour envoyer au client2
    canal1retour = client1: pour reçevoir du client1
    canal2retour = client2: pour recevoir du client2
    */
     
    //Dit au 2 joueurs qu'ils peuvent encoder leur grilles
    if (write(canal1aller,"Z",1)==1) printf("\nj1=OK"); else printf("\nj1=KO");
    if (write(canal2aller,"Z",1)==1) printf("\nj2=OK"); else printf("\nj2=KO");
    /*
    //Reception des grilles.
    //joueur 1
    read(canal1retour,grilleclients[0],121);
    write(canal1aller,"O",2); //accusé de réception grille joueur 1
    //joueur 2
    read(canal2retour,grilleclients[1],121);
    write(canal2aller,"O",2); //accusé de réception grille joueur 2*/
    }


    Voilà. N'hésitez pas à posez vos questions. Merci

  2. #2
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    personne ne sait m'aider?

  3. #3
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    D'après ce que j'a compris , tu souhaite faire communiquer 3 processus :
    Un serveur
    Deux clients.

    D'après ton système , tes processus devront tourner sur la même machine ( a moins que je n'ai rien compris au FIFO ( qui pour moi veut dire Fisrt In Fisrt Out ) ), ce qui me semble être contreignant.

    Pourquoi ne pas te renseigner du coté des sockets ?
    Tu pourrai de cette facon , avoir une communication interprocessus assez facile tout en permetant a tes processus d'être sur des machines différentes.

  4. #4
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    oui donc tu as tout a fait compris. Il faut 2 canal de communications entre le serveur et le client.
    J'ai eu le choix de faire comme celà mais j'ai entamer le projet comme ça et je ne vais aps changer.
    J'ai trouvé une solution pour que les clients puissent envoyer leur grille mais les client n'arrive jamais à reçevoir les infos du serveur (par ex, ok début de la partie).
    Donc le client envoi bien au serveur mais il n'arrive pas a recevoir du serveur. J'ai bien vérifié que le serveur a bien écrit la donnée en plus. Bizarre.

  5. #5
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    J'ai eu le choix de faire comme celà mais j'ai entamer le projet comme ça et je ne vais pas changer.
    .
    Ah.La sacro-sainte règle du 'pas touche au code qui marche' et du 'j'ai commencé comme ca, peut pas changer'.
    Je pense peut toujours changer au prix de remmetre en question son code et sa conception(et ca m'est arrivé plus d'une fois).

    Je pense aussi personnellement qu'utiliser des pipes pour la communication inter-process dans ce cadre est plus qu' inapproprié .
    Les seuls cas ou j'ai utilisé les pipes , c'est dans le cadre de communication de processus père à fils ou dans des cas approchant (processus que je qualifie de 'frères').

    Je pense que dans ton cas, les sockets serait bien plus simple a mettre en oeuvre que les pipe ( bien que socket et pipe repose sur le même principe ) et offirait bien plus de modularité puisqu'ils ont été concu pour assurer la communication entre des processus situé sur différente machine(physique mais aussi 'logique'[Os différent,...]) et le tout de manière normalisé et transparente.

    Mais si tu souhaite continuer avec les pipes(ce que je déconseille fortement[j'enfonce le clou]) : voici un cours sur les pipes qui pourais t'être utile : http://www.etis.ensea.fr/~revel/html/frame_titre.html (Enseignement -> Unix -> pipe )

Discussions similaires

  1. Réponses: 4
    Dernier message: 22/09/2010, 09h30
  2. [Lazarus] [Linux] Problème avec les points d'arrêts
    Par ovni76 dans le forum Lazarus
    Réponses: 6
    Dernier message: 15/02/2010, 22h45
  3. [Lazarus] [0.9.26/Linux] Problème avec DBGrid et TDBF
    Par ovni76 dans le forum Lazarus
    Réponses: 2
    Dernier message: 02/02/2009, 19h57
  4. Problèmes avec la communication série
    Par rzayani dans le forum Windows
    Réponses: 3
    Dernier message: 18/06/2007, 11h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo