我一直在努力理解先进先出(FIFO),并编写了一个简单的服务器和客户端程序。
我不想做什么高深的事情,只是要有一个进程充当“服务器”的角色,该进程将“监听”另一个进程(客户端)发送的任何消息。
这是我的代码:
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;
}
这是客户端。代码也很简单。当我在shell中使用
./a.out
运行它时,它可以发送消息,而server.out
进程会打印You sent %s to server.
问题在于,当我通过客户端向服务器发送
Quit
时,尽管a.out
进程按预期终止,但是server.out
中的while
循环也会停止。这意味着read
不再阻塞server.out
进程并等待其他客户机,而是服务器程序和客户端一起结束。为什么会发生这种情况?即使
a.out
进程结束后,read
不应该仍然挂起server.out
吗?
printf
将打印一个未终止的字符串。 - Some programmer dudewrite(out_fd, input, strlen(input)+1)
? - so.very.tiredint nbytes; while ((nbytes = read(in_fd, in, sizeof(in))) > 0) printf("你发送了 [%.*s] 到服务器\n", nbytes, in);
方括号用于标记已发送的数据(因此是可选的)。 - Jonathan Leffler