场景描述:
多个客户端同时和服务端进行通信,客户端发送buf至服务端,服务端进程处理。将buf中的英文字母全部转为大写,之后返回给客户端。
实现原理:
服务端以阻塞的方式打开一个命名管道(O_RDONLY),客户端以阻塞的方式打开这个管道(O_WRONLY)并写入数据。
因为是阻塞方式,有数据进行写入,服务端才开始处理。至于是如何同步,是在open的时候处理的。服务端处理之后,将处理后的结果写入对应的客户端的命名管道。
而客户端的管道命名需加上自己的标识。客户端处理完毕之后,关闭自己的客户端管道和服务端管道,删除自己的客户端管道。
头文件如下: client.h
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <fcntl.h>
#define SERVER_FIFO_NAME "/tmp/serv_fifo"
#define CLIENT_FIFO_NAME "/tmp/cli_%d_fifo"
#define BUFFER_SIZE 20
struct data_to_pass_st{
pid_t client_pid;
char some_data[BUFFER_SIZE-1];
};
服务端代码如下: server.c
#include "client.h"
#include <ctype.h>
int main(int argc,char **argv)
{
int server_fifo_fd,client_fifo_fd;
struct data_to_pass_st my_data;
int read_res;
char client_fifo[256];
char *tmp_char_ptr;
mkfifo(SERVER_FIFO_NAME,0777);
server_fifo_fd = open(SERVER_FIFO_NAME,O_RDONLY);
if(server_fifo_fd == -1){
fprintf(stderr,"Server fifo failure!\n");
exit(-1);
}
sleep(10);
do{
read_res = read(server_fifo_fd,&my_data,sizeof(my_data));
if(read_res > 0){
tmp_char_ptr = my_data.some_data;
while(*tmp_char_ptr){
*tmp_char_ptr = toupper(*tmp_char_ptr);
tmp_char_ptr++;
}
sprintf(client_fifo,CLIENT_FIFO_NAME,my_data.client_pid);
client_fifo_fd = open(client_fifo,O_WRONLY);
if(client_fifo_fd != -1){
write(client_fifo_fd,&my_data,sizeof(my_data));
close(client_fifo_fd);
}
}
}while (read_res > 0);
close(server_fifo_fd);
unlink(SERVER_FIFO_NAME);
exit(0);
}
客户端代码: client.c
#include "client.h"
#include <ctype.h>
int main(int argc,char **argv)
{
int server_fifo_fd,client_fifo_fd;
struct data_to_pass_st my_data;
int times_to_send;
char client_fifo[256];
server_fifo_fd = open(SERVER_FIFO_NAME,O_WRONLY);
if(server_fifo_fd == -1){
fprintf(stderr,"Sorry,no server\n");
exit(-1);
}
my_data.client_pid = getpid();
sprintf(client_fifo,CLIENT_FIFO_NAME,my_data.client_pid);
if(mkfifo(client_fifo,0777) == -1){
fprintf(stderr,"Sorry,can't make %s\n",client_fifo);
exit(-1);
}
for(times_to_send = 0;times_to_send < 5;times_to_send++){
sprintf(my_data.some_data,"Hello from %d",my_data.client_pid);
printf("%d sent %s, ",my_data.client_pid,my_data.some_data);
write(server_fifo_fd,&my_data,sizeof(my_data));
client_fifo_fd = open(client_fifo,O_RDONLY);
if(client_fifo_fd != -1){
if(read(client_fifo_fd,&my_data,sizeof(my_data)) > 0){
printf("received: %s\n",my_data.some_data);
}
close(client_fifo_fd);
}
}
close(server_fifo_fd);
unlink(client_fifo);
exit(0);
}
运行:
./server &
for i in 1 2 3 4 5
do
./client &
done