2014-05-02 145 views
3

我一直试图围绕FIFO,并提出了一个简单的程序的服务器和客户端。
我不是想做任何事情,只是为了让一个进程扮演'服务器'的角色,这个进程将'监听'由另一个进程传递的任何消息;客户端。
这是我写的:写入/读取/从FIFO文件 - linux

server.c

#include<stdio.h> 
#include <fcntl.h> 
#include <stdlib.h> 


#define INGOING "clientToServer.fifo" 

#define BUFFER 200 

int main(int argc, char *argv[]) { 

    char in[BUFFER]; 

    mkfifo(INGOING, 0666); 

    printf("Welcome to server.\n"); 
    printf("channel for sending messages to server is %s\n", INGOING); 

    int in_fd=open(INGOING, O_RDONLY); 

    if (in_fd==-1) { 
     perror("open error"); 
     exit(-1); 
    } 

    while (read(in_fd, in, BUFFER)>0) { 
     printf("You sent %s to server.\n", in); 
    } 

    return 2; 
} 

正如你可以看到,这是相当直接的,当我跑这在背景./server.out&它挡在read呼叫并等待任何人都可以写信给clientToServer.fifo。到现在为止还挺好。

现在,考虑客户端:
client.c

#include<stdio.h> 
#include<fcntl.h> 
#include<string.h> 


#define BUFFER 200 

int main(int argc, char *argv[]) { 

    char input[BUFFER]={0}; 
    int out_fd=open("clientToServer.fifo", O_WRONLY); 

    if (out_fd==-1) { 
     perror("open error"); 
    } 

    while (1) { 

     printf("What would you like to send to server? (send Quit to quit)\n"); 
     fgets(input, BUFFER, stdin); 
     if (input[strlen(input)-1]=='\n') { 
      input[strlen(input)-1]='\0'; 
     } 

     if (strcmp(input, "Quit")==0) { 
      printf("Bye!"); 
      break; 
     } 

     if (write(out_fd, input, strlen(input))==-1) { 
      perror("write error"); 
     } 
    } 

    return 1; 
} 

这是客户端。也很简单的代码。当我./a.out从外壳运行它,它的工作原理 - 它发送消息,并且server.out过程打印You sent %s to server.
问题是,当我通过客户端向服务器发送Quit,尽管如所期望的a.out进程终止时,while环在server.out也休息。这意味着,read不再阻止server.out进程并等待其他客户端,而是服务器程序与客户端一起结束。
这是怎么发生的? read应该不会暂停server.out再次,即使在a.out过程结束后?

+0

您的代码中存在未定义的行为:您从客户端发送没有终止符的字符串,并且在未添加添加终止符的情况下读取该字符串,这意味着服务器中的printf会打印未终止的字符串。 –

+0

@JoachimPileborg,so:'write(out_fd,input,strlen(input)+1)'? –

+0

否:'int nbytes; while((nbytes = read(in_fd,in,sizeof(in)))> 0)printf(“您发送[%。* s]到服务器\ n”,nbytes,in);'方括号在哪里分隔发送的数据(因此是可选的)。 –

回答

8

,当我跑在这个背景./server.out &它挡在读的呼叫并等待任何人写信给clientToServer.fifo

其实这块在open。这是FIFOs的工作方式。 open(处于阻塞模式)将阻塞,直到另一端打开FIFO。

server.out中的while循环也会中断。意思是,读取不再阻止server.out进程并等待其他客户端,而是服务器程序结束

此外,这是正常行为。只有一个客户端进程连接到FIFO,所以当它关闭它的结束时,EOF被发送,服务器退出。如果多个客户端同时连接到FIFO,则在最后一个客户端关闭它之前您将看不到EOF。如果您想要一个长时间运行的服务器为多个客户端连续提供服务,最简单的方法是以读/写方式打开服务器的FIFO。这样,总是有一个读写器 - 服务器本身 - 并且即使最后一个客户端退出时也不会看到EOF。当关闭服务器的时候,关闭服务器中的适当的一端,让真正的客户端退出,让自然走向成熟。

+0

谢谢。我在哪里可以找到详细解释所有这些的手册?我无法在linux手册中找到它... –

+1

我不确定这些东西本身是否有手册。没有替代一个好的,详细的UNIX书籍和迭代密切阅读的手册页。网络上有很多不同质量的素材。似乎受到高度重视的是[Beej's Guides](http://beej.us/guide/bgipc/output/html/multipage/index.html) – Duck

+0

这看起来正是我所需要的! :-) –

1

当客户端退出时关闭管道连接,导致服务器中的read函数返回退出循环的0

+0

当我最初运行'server.out'时,为什么它会在'read'处停止进程?在运行'a.out'之前没有任何开放的管道连接。 –