无法将stdin重定向到另一个进程并让该进程正确回答

时间:2017-01-13 20:53:15

标签: c pipe stdout stdin fifo

我有一个项目要做C,我必须制作一个游戏,其中2个客户端与服务器通话,并且该服务器处理游戏,然后响应每个游戏,当时一个,直到游戏是完了。 我现在已经这样做了几个星期,我设法做了类似的事情:

  1. 服务器有一个fork,其中child,exec()是一个游戏(由我提供),我将该输出重定向到客户端(非常粗略地我可能会添加...),以及一个未命名的管道用于说话和他的父母一起。

  2. 客户端收到该输出,看到游戏板并向服务器发送游戏。

  3. 父级使用未命名管道的另一端接收客户端发送的内容并将其发送给子级。

  4. 第一次播放完成后,服务器进入“无效播放”循环,但我不发送任何内容。到底是怎么回事?有人能指出我正确的方向吗?

    这个项目的限制是我们只能使用管道和fifos(不是线程或套接字)以及打开,关闭,读取和写入。 game.c代码只允许printfs。

    跑步示例:

    使用./server打开服务器,使用./client John打开客户端。在客户端中,键入1并输入。然后输入1 1并输入以进行播放。然后,发生错误。

    client.c

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <string.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <linux/limits.h>
    #include <stdlib.h>
    #include <signal.h>
    
    void main(int argc, char *argv[])
    {
    
    int fdfifo_CS, fdfifo_SC, fd, conta;
    char buffer[400];
    int num=0;  
    
    fdfifo_CS = open("fifo_publico_cliente_servidor", O_WRONLY);        
    
    fdfifo_SC = open("fifo_privado_servidor_cliente", O_RDONLY);
    
    write(fdfifo_CS, argv[1], strlen(argv[1])+1);               
    
    while(1)
    {
        num = read(fdfifo_SC,buffer,sizeof(buffer)); 
            write(1,buffer,num);
    
        num = read(0,buffer,sizeof(buffer));        
            write(fdfifo_CS, buffer, num);
    
        num = read(0,buffer,sizeof(buffer));        
            write(fdfifo_CS, buffer, num);
    }
    

    server.c

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <string.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <linux/limits.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <dirent.h>
    
    void main(int argc, char *argv[])
    {
    int fdfifo_CS, fdfifo_SC, num=0, pid=0, fd, pipefd[2];
    char buffer[1024];
    
    write(1, "\nServer ON !\n", strlen("\nServer ON !\n"));
    
    mkfifo("fifo_publico_cliente_servidor",0777);
    
    fdfifo_CS = open("fifo_publico_cliente_servidor", O_RDWR);  
    
    mkfifo("fifo_privado_servidor_cliente",0777);
    
    fdfifo_SC = open("fifo_privado_servidor_cliente", O_WRONLY);
    
    num = read(fdfifo_CS,&buffer,sizeof(buffer));
    
    do
    {
        write(fdfifo_SC,"\n\n!!! Menu !!!\n", strlen("\n\n!!! Menu !!!\n"));
        write(fdfifo_SC,"----------------------------------------------\n", strlen("----------------------------------------------\n"));
        write(fdfifo_SC,"1) Play.\n", strlen("1) Play.\n"));
    
        write(fdfifo_SC,"Choose: ", strlen("Choose: "));
    
        read(fdfifo_CS,buffer,sizeof(buffer));
    
        switch(buffer[0])
        {
            case '1':
    
                        pipe(pipefd);
    
                        pid = fork();
                        if (pid == 0) 
                        {
                            fd = open("/dev/pts/8", O_RDWR, 0777); //To redirect to the bash of the client used. Must be changed to the correct tty.
                                dup2(fd,1);
                                close(fd);
    
                            close(pipefd[1]);
                            dup2(pipefd[0],0);
                            close(pipefd[0]);
    
                            execl("game","game",(char*) NULL);
                        }
                        else 
                        {
                            close(pipefd[0]); 
    
                            num = read(fdfifo_CS, buffer, sizeof(buffer));
                                write(pipefd[1], buffer, num);
    
                            close(pipefd[1]);
    
                        }
    
                    break;
    
            default:
                printf("DONE");
                break;
        }
        }while(1);
    }
    

    game.c

    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    
    void print_table(char *p, char t[3][3]) {
        printf("\nO:%s:  %c|%c|%c\n", p, '1', '2', '3');
        printf("O:%s:1 %c|%c|%c\n", p, t[0][0], t[0][1], t[0][2]);
        printf("O:%s:  -+-+-\n", p);
        printf("O:%s:2 %c|%c|%c\n", p, t[1][0], t[1][1], t[1][2]);
        printf("O:%s:  -+-+-\n", p);
        printf("O:%s:3 %c|%c|%c\n\n", p, t[2][0], t[2][1], t[2][2]);
    }
    
    /* check if this was a winning play */
    int winning_play(int x, int y, char t[3][3]) {
        int v = t[y-1][x-1];
        if (t[y-1][0] == v && t[y-1][1] == v && t[y-1][2] == v)
                return 1;
        if (t[0][x-1] == v && t[1][x-1] == v && t[2][x-1] == v)
                return 1;
        if ((x + y % 2 == 0 && /* part of a diagonal */
            t[0][0] == v && t[1][1] == v && t[2][2] == v) ||
            (t[0][2] == v && t[1][1] == v && t[2][0] == v))
                return 1;
        return 0;
    }
    
    int main() {
        char table[3][3] = 
            { {' ', ' ', ' '}, {' ', ' ', ' '}, {' ', ' ', ' '} };
        char play[16];
        int stop = 0, win = 0, turn = 1, turns = 0;
        do {
            int x, y, check;
            /* display table to both players */
            print_table("12", table);
            turn = (turn + 1) % 2;
            turns++;
            do {
                /* display message to the current player */
                printf("OUT:%d: play (format \"x y\")?\n", turn+1);
                /* ask for input from current player */
                printf("IN:%d\n", turn+1);
                fgets(play, sizeof(play), stdin);
                check = (sscanf(play, "%d%d", &x, &y) == 2 &&
                    x >= 1 && x <=3 && y >= 1 && y <= 3 &&
                    table[y-1][x-1] == ' ');
                if (check == 0)
                    /* display message to current player */
                    printf("OUT:%d: invalid play\n", turn+1);
            } while (!check);
            table[y-1][x-1] = (turn == 0 ? 'X' : 'O');
            win = winning_play(x, y, table);
            stop = (turns == 9);
        } while (!stop && !win);
        /* display final table to both players */
        print_table("12", table);
        /* display final score to both players */
        if (win)
            printf("RES:12: winner %d\n", turn+1);
        else
            printf("RES:12: draw\n");
        return 0;
    }
    

0 个答案:

没有答案