有名管道+多进程最基本的并发式的通信

一.之前的有名管道实现的服务器-客户端程序只能实现你一句我一句的基本的通信。要实现最最基本的并发式通信,需要引入多个进程

真正的并发式通信不再是一个服务器针对一个客户端这种一对一的模式,而是一对多的模式。这里其实还谈不上并发。
二.代码
1.server.c

/*并发式,不再是你一句我一句
 * QQ聊天
 * */
#include"utili.h"

int main()
{
    char sendbuf[MAX_MSG_LEN];
    char recvbuf[MAX_MSG_LEN];
    if(access(FIFO_WRITE, F_OK) == -1)
    {
        int res = mkfifo(FIFO_WRITE, 0666);//0表示8进制
        if(res == -1)
        {
            perror("mkfifo WRITE");
            exit(EXIT_FAILURE);
        }
    }
    //以只写方式打开,会阻塞到有读方式打开管道
    int wfd = open(FIFO_WRITE, O_WRONLY);
    if(wfd == -1)
    {
        perror("open WRITE");
        exit(EXIT_FAILURE);
    }
    //以只读方式打开,会阻塞到有写方式打开管道
    int rfd = open(FIFO_READ, O_RDONLY);
    if(rfd == -1)
    {
        perror("open READ");
        exit(EXIT_FAILURE);
    }
    pid_t pid = fork();
    if(pid == 0)//子进程负责读入数据
    {
        while(1)
        {
            read(rfd, recvbuf, MAX_MSG_LEN);
            printf("Cli:>%s\n", recvbuf);
            if(strcmp(recvbuf, "quit") == 0)
                exit(EXIT_FAILURE);
        }
    }
    else if(pid > 0)
    {
        pid_t pid1 = fork();
        if(pid1 == 0)
        {
            while(1)
            {
                printf("Ser:>");
                signal(SIGINT, handler);
                scanf("%s", sendbuf);
                write(wfd, sendbuf, strlen(sendbuf)+1);
            }
        }
        else if(pid1 > 0)
        {
                int stat;
                wait(&stat);
                wait(&stat);
        }
    }
}

2.client.c

#include"utili.h"

int main()
{
    char recvbuf[MAX_MSG_LEN];
    char sendbuf[MAX_MSG_LEN];
    int wfd, rfd;
    if(access(FIFO_READ, F_OK) == -1)
    {
        int res = mkfifo(FIFO_READ, 0666);
        if(res == -1)
        {
            perror("mkfifo READ");
            exit(EXIT_FAILURE);
        }
    }
    //server的写对应client读
    rfd = open(FIFO_WRITE, O_RDONLY);
    if(rfd == -1)
    {
        perror("open READ");
        exit(EXIT_FAILURE);
    }
    wfd = open(FIFO_READ, O_WRONLY);
    if(wfd == -1)
    {
        perror("open WRITE");
        exit(EXIT_FAILURE);
    }

    pid_t pid = fork();
    if(pid == 0)//子进程用于写
    {
        while(1)
        {
            printf("Cli:>");
            scanf("%s", sendbuf);
            write(wfd, sendbuf, strlen(sendbuf)+1);
            if(strcmp(sendbuf, "quit") == 0)
                exit(EXIT_FAILURE);
        }
    }
    else if(pid > 0)
    {
        pid_t pid1 = fork();
        if(pid1 == 0)
        {
            while(1)
            {
                read(rfd, recvbuf, MAX_MSG_LEN);
                printf("Ser:>%s\n", recvbuf);
            }
        }
        else if(pid > 0)
        {
            int stat;
            wait(&stat);
            wait(&stat);
        }
    }
}

3.utili.h

#ifndef _UTILI_H_
#define _UTILI_H_

#include<stdio.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
#include<sys/wait.h>

#define FIFO_READ "readfifo"
#define FIFO_WRITE "writefifo"
#define MAX_MSG_LEN 256
void handler(int signum)
{
    unlink(FIFO_READ);
    unlink(FIFO_WRITE);
    exit(1);
}

#endif

4.Makefile

CC=gcc
OUT=-o
all:server client
server:server.c
    $(CC) server.c $(OUT) server -std=c99
client:client.c
    $(CC) client.c $(OUT) client -std=c99
.PHONY:clean
clean:
    /bin/rm -f server client

三.代码测试
这里写图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值