服务器应答客户端请求抛出管道和管道C.

时间:2017-12-13 10:57:21

标签: c fork named-pipes

  • 简短版本:

我试图抛出一个客户发送的请求,让他回想起他希望我找到的表达式的结果。

  • 更长版本:

为此,我首先使用mkfifo创建两个命名管:一个用于服务器,一个用于客户端。客户端将自己连接到服务器的命名管并写入请求。服务器将读取并使用fork将确定message->表达式的结果(抛出bc)。在此之后,他将自己连接到客户端的命名管(管的名称=客户端的pid)并发回结果。最后客户打印它。

我已经问过fork和bc是如何工作的,我们应该使用所有的重定向。当我在程序中不使用mkfifo(并在之前创建服务器和客户端的命名管)时,这确实有效。我想我误解了open和mkfifo的正确用法。我试图捕捉尽可能多的错误,但这对我没有多大帮助。

这里的代码是:-SERVER -

    #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#define BUFFER_SIZE 20

typedef struct requete_client_serveur {
    pid_t client_pid;               //PID's clients
    char expression[BUFFER_SIZE-1]; //expression
}requete_client_serveur;

int main(){

    char resultat[5];
    int t1;
    int mk;


    //create server's named pipe
    char *fifoServeur = "serveurfifo";
    printf("%s\n", fifoServeur);

    if((mk = mkfifo(fifoServeur, 0777)) == -1 ){
        fprintf(stderr, "mkfifo's server failed \n");
        exit(EXIT_FAILURE);
    }

    printf("Hello\n");

    //open server's named pipe
    if ((t1 = open(fifoServeur, O_RDONLY)) == -1){
        fprintf(stderr, "open server's named pipe failed \n");
        exit(EXIT_FAILURE);
    }


    //While there are clients
    while(1){

        //For read the client's request
        requete_client_serveur* rcs = malloc(sizeof(requete_client_serveur));
        requete_client_serveur* message = (requete_client_serveur*) rcs;

        //Read the expression
        int nbytes = read(t1, rcs, sizeof(*rcs));
        if (nbytes <= 0)
            fprintf(stderr, "read from child failed\n");
            exit(EXIT_FAILURE);


        printf("expression the client %d send : %s\n",getpid(),message->expression);


        //creation two tubes
        int pipe1[2];
        int pipe2[2];
        pipe(pipe1);
        pipe(pipe2);

        //fork
        int resultat_fork = fork();
        if (resultat_fork == -1)
            exit(EXIT_FAILURE);


        if(resultat_fork!=0){ 
            printf("I am the parent\n");

            close(pipe1[0]);
            close(pipe2[1]);
            /* We don't need pipe1's input and pipe2's output */

            if (write(pipe1[1],message->expression, strlen(message->expression)) != strlen(message->expression))
                fprintf(stderr, "write to child failed\n");
                exit(EXIT_FAILURE);

            //open client's tube
            int t2;
            char fifoClient[10];

            sprintf(fifoClient,"%u", message->client_pid);

            printf("%s\n", fifoClient);

            if ((t2 = open(fifoClient, O_WRONLY)) == -1){
                fprintf(stderr, "open client's named pipe failed \n");
                exit(EXIT_FAILURE);
            }


            /* Write the answer into the client's tube (here t2) */
            if(write(t2, resultat, sizeof(resultat)) != sizeof(resultat))
                    fprintf(stderr, "write to client (t2) failed\n");
                    exit(EXIT_FAILURE);



            close(pipe1[1]);
            close(pipe2[0]);
            /* We don't need them anymore */



        }else{
            printf("I am the children\n");

            close(pipe1[1]);
            close(pipe2[0]);
            /* We don't need pipe1's output and pipe2's input */

            dup2(pipe1[0], 0);  
            dup2(pipe2[1], 1);
            /* Redirection input & output */

            close(pipe1[0]);
            close(pipe2[1]);
            /* More closes */

            execlp("bc", "bc", NULL);
            fprintf(stderr, "Failed to execute bc\n");
            exit(EXIT_FAILURE);
        }

    }
}

客户:

    #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>


#define BUFFER_SIZE 20

typedef struct requete_client_serveur {
    pid_t client_pid;               //PID's clients
    char expression[BUFFER_SIZE-1]; //expression
}requete_client_serveur;

int main(){

    int t1,t2;
    char resultat[5];

    //open serveur's named tube
    char *fifoServeur = "serveurfifo";

    if((t1 = open(fifoServeur, O_WRONLY)) == -1){
        fprintf(stderr, "open server's named pipe failed \n");
        exit(EXIT_FAILURE);
    }

    //create client's named tube using his pid as descriptor
    pid_t pid = getpid();
    char fifoClient[10];
    int mk;

    sprintf(fifoClient,"%u", pid);
    printf("%s\n", fifoClient);
    if((mk = mkfifo(fifoClient, 0777)) == -1){
        fprintf(stderr, "open client's named pipe failed \n");
        exit(EXIT_FAILURE);
    }

    printf("%d\n",mk);  

    printf("cc\n");

    //Open it as a reader
    if ((t2 = open(fifoClient, O_RDONLY)) == -1){
        fprintf(stderr, "open client's named pipe failed \n");
        exit(EXIT_FAILURE);
    }

    printf("cc\n");

    //preparation request
    void* bc = malloc(sizeof(requete_client_serveur));
    requete_client_serveur* rcs = (requete_client_serveur*) bc;


    //expression we want to compute
    char *expression = "5*5\n";

    rcs->client_pid = pid;
    strcpy(rcs->expression, (char *)expression);


    //write the request to the server
    if (write(t1, rcs, sizeof(rcs)) != sizeof(rcs))
        fprintf(stderr, "write to server from client (t1) failed\n");


    //read the answer
    int nbytes = read(t2, resultat, sizeof(resultat));
    if (nbytes <= 0)
            fprintf(stderr, "read result failed\n");
            exit(EXIT_FAILURE);

    //printf it
    printf("resultat: %s\n", resultat);
}

当开始这两个过程时,我一直没有从服务器和客户端得到任何东西(没有错误或有时如果我很幸运)。如果您有任何想法帮助我使用该系统,我将非常感激。我没有必要得到答案,我真的想知道它是如何工作的。 感谢您的阅读(请原谅我的语法错误,英语不是我的主要语言)。

0 个答案:

没有答案