Unix/Linux 管道的简单应用- 客户端和服务端通信

场景描述:

    多个客户端同时和服务端进行通信,客户端发送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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值