【问题标题】:Proper FIFO client-server connection正确的 FIFO 客户端-服务器连接
【发布时间】:2012-01-26 12:24:46
【问题描述】:

我正在尝试编写简单的客户端和服务器 C 程序,在不同的终端中相互通信。

服务器必须创建一个公共 fifo 并等待客户端。同时,客户端正在创建自己的先进先出,服务器的响应将通过该先进先出。客户端的任务是向服务器发送队列创建的名称,并返回ls 命令的结果。

我确实搜索了答案,例如:fifo-server-programexample-of-using-named-pipes-in-linux-bashhow-to-send-a-simple-string-between-two-programs-using-pipes。我从第三个链接的代码开始,慢慢修改。

我现在得到的是一个客户端,它从用户那里获取输入,将其发送到服务器并接收回来。但它只工作一次。我不知道为什么。 main函数的主体如下。如有任何帮助,我将不胜感激。

编辑: 我让它工作了! :D 代码如下,也许它会对某人有所帮助。

server.c 代码:

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

int main(int argc, char* argv[])
{
    int fds[2];
    char tab[BUFSIZ];
    int fd, n;

    char *myfifo = "/tmp/serwer";
    char *myfifo2 = "/tmp/client";

    pipe(fds);
    mkfifo(myfifo,0666);

    while(1)
    {
        fds[0]=open(myfifo2,O_RDONLY);
        fds[1]=open(myfifo,O_WRONLY);

        read(fds[0],tab,BUFSIZ);

        if (strcmp("klient",tab)==0) {
            printf("Od klienta: %s\n",tab);
            fd=open(tab,O_WRONLY);

            if(fork()==0)
            {
                dup2(fds[1],1);
                close(fds[1]);
                execlp("ls","ls","-l",NULL);
                close(fds[0]);
                close(fds[1]);
            }
            else
            {
                dup2(fds[0],0);
                n = read(fds[0],tab,BUFSIZ);
                write(fd,tab,n);
                close(fds[0]);
                close(fds[1]);
            }
        }
        memset(tab, 0, sizeof(tab));
        close(fd);
        close(fds[0]);
        close(fds[1]);
    }

    unlink(myfifo);
    return 0;
}

client.c 代码:

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

int main(int argc, char* argv[])
{
    int fds[2];
    char *myfifo = "/tmp/serwer";
    char *myfifo2 = "/tmp/client";

    mkfifo(myfifo2,0666);
    fds[0]=open(myfifo,O_RDONLY);
    fds[1]=open(myfifo2,O_WRONLY);

    char tab[BUFSIZ];
    memset(tab, 0, sizeof(tab));

    write(fds[1],"klient",6);
    perror("Write:"); //Very crude error check
    read(fds[0],tab,sizeof(tab));
    perror("Read:"); // Very crude error check

    printf("Odebrano od serwera: %s\n",tab);

    close(fds[0]);
    close(fds[1]);
    unlink(myfifo2);
    return 0;
}

【问题讨论】:

  • 从这段代码中看不出来。您是否使 ls 输出正常工作,或者您只是发送小消息?在这种情况下,通常的陷阱是死锁,即服务器在等待输入,而客户端在等待输入。他们永远等待,因为没有人发送任何东西。
  • 不,ls 命令还没有工作。这些程序工作一次——服务器等待消息,将其返回给客户端,客户端可以关闭。当我想发送另一条消息时,客户端和服务器都没有响应。

标签: c linux client-server mkfifo


【解决方案1】:

由于命名管道的工作方式,它只能工作一次。每次您open 一个用于读取的命名管道时,您都会阻塞,直到另一个进程打开它进行写入。然后你配对并且文件描述符连接你的进程。一旦任一端关闭该连接,即是该管道的末端。为了让您的服务器“接受另一个连接”,它需要将管道的 openclose 移动到其主循环中,以便它可以一遍又一遍地配对。

【讨论】:

    【解决方案2】:

    你为什么不管理服务器中的两个fifo?只需更改您的代码即可使其正常工作。

    如果你真的想建立一个客户端-服务器关系,一个服务器服务于许多不同的客户端,那么套接字可能是一个更好的选择。

    client.cpp

    #include <stdio.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main()
    {
       int client_to_server;
       char *myfifo = "/tmp/client_to_server_fifo";
    
       int server_to_client;
       char *myfifo2 = "/tmp/server_to_client_fifo";
    
       char str[BUFSIZ];
       printf("Input message to serwer: ");
       scanf("%s", str);
    
    
       /* write str to the FIFO */
       client_to_server = open(myfifo, O_WRONLY);
       server_to_client = open(myfifo2, O_RDONLY);
       write(client_to_server, str, sizeof(str));
    
       perror("Write:"); //Very crude error check
    
       read(server_to_client,str,sizeof(str));
    
       perror("Read:"); // Very crude error check
    
       printf("...received from the server: %s\n",str);
       close(client_to_server);
       close(server_to_client);
    
       /* remove the FIFO */
    
       return 0;
    }
    

    服务器.cpp

    #include <fcntl.h>
    #include <stdio.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <string.h>
    
    int main()
    {
       int client_to_server;
       char *myfifo = "/tmp/client_to_server_fifo";
    
       int server_to_client;
       char *myfifo2 = "/tmp/server_to_client_fifo";
    
       char buf[BUFSIZ];
    
       /* create the FIFO (named pipe) */
       mkfifo(myfifo, 0666);
       mkfifo(myfifo2, 0666);
    
       /* open, read, and display the message from the FIFO */
       client_to_server = open(myfifo, O_RDONLY);
       server_to_client = open(myfifo2, O_WRONLY);
    
       printf("Server ON.\n");
    
       while (1)
       {
          read(client_to_server, buf, BUFSIZ);
    
          if (strcmp("exit",buf)==0)
          {
             printf("Server OFF.\n");
             break;
          }
    
          else if (strcmp("",buf)!=0)
          {
             printf("Received: %s\n", buf);
             printf("Sending back...\n");
             write(server_to_client,buf,BUFSIZ);
          }
    
          /* clean buf from any data */
          memset(buf, 0, sizeof(buf));
       }
    
       close(client_to_server);
       close(server_to_client);
    
       unlink(myfifo);
       unlink(myfifo2);
       return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-25
      • 1970-01-01
      • 2016-07-06
      • 1970-01-01
      • 1970-01-01
      • 2022-09-28
      • 2020-06-26
      • 1970-01-01
      • 2012-03-27
      相关资源
      最近更新 更多