使用FIFO管道的客户端-服务器通信问题

时间:2019-12-30 17:58:56

标签: c unix server client fifo

我正在为我的学校编写一个项目,我需要一些帮助。

项目说明: 客户端将整数表发送到服务器。服务器将表中的所有数字相加并发送回结果。服务器类型为:并发。通信协议是:命名为FIFO管道。项目要求:使用线程,并发服务器,使用C语言和命名的FIFO管道。

问题:客户端程序在打开fifo时冻结,因此我发现只有在永久打开fifo写入数据时才可以打开fifo读取数据。

我的代码:

client.c:

#include "common.h"

int main(void)
{
    pid_t mypid = getpid();
    char filename[80];
    sprintf(filename, "%lld.fifo", mypid);
    if(mkfifo(filename, 0660) < 0)
    {
        fprintf(stderr, "Failed to create client fifo");
        exit(-1);
    }
    int fd1, fd2;
    fd1 = open("server.fifo", O_WRONLY, 0);
    // int dummy = open(filename, O_WRONLY, 0);
    fd2 = open(filename, O_RDONLY, 0);
    if((fd1 < 0) || (fd2 < 0))
    {
        fprintf(stderr, "Failed to open one or more fifo's");
        exit(-1);
    }
    long long int *array = NULL;
    long long int size;
    printf("Type array size: ");
    scanf("%lld", &size);
    array = malloc(size * sizeof(long long int));
    for(long long int i = 0; i < size; i++)
    {
        printf("Type %lld array element: ", i+1);
        scanf("%lld", array[i]);
    }
    struct CMB_IC cmbIcMsg;
    cmbIcMsg.client_pid = getpid();
    write(fd1, &cmbIcMsg, sizeof(struct CMB_IC));
    struct CMB cmbMsg;
    for(long long int i = 0; i < size; i++)
    {
        if(i == size - 1)
            cmbMsg.EOV = true;
        else
            cmbMsg.EOV = false;
        cmbMsg.vector_atom = array[i];
        write(fd1, &cmbMsg, sizeof(struct CMB));
    }
    struct SMB smbMsg;
    while(read(fd2, &smbMsg, sizeof(struct SMB)) == 0);
    printf("Suma wynosi: %lld", smbMsg.suma);
    return 0;
}

common.h:

#include <sys/types.h>
#include <stdbool.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>

struct SMB
{
    long long int suma;
};

struct CMB_IC
{
    pid_t client_pid;
};

struct CMB
{
    long long int vector_atom;
    bool EOV;
};

server.c:

#include <pthread.h>
#include "common.h"
#include <semaphore.h>

int fd1, fd2;
char filename[80];
sem_t main_sem;

int main(void)
{
    if(mkfifo("server.fifo", 0660) < 0)
    {
        // int dummy = open("server.fifo", O_WRONLY, 0);
        fd1 = open("server.fifo", O_RDONLY, 0);
    }
    else
    {
        // int dummy = open("server.fifo", O_WRONLY, 0);
        fd1 = open("server.fifo", O_RDONLY, 0);
    }
    sem_init(&main_sem, 0, 1);
    struct CMB_IC cmbIcMsg;
    while(true)
    {
        while(read(fd1, &cmbIcMsg, sizeof(struct CMB_IC)) == 0);
        sem_wait(&main_sem);
        sprintf(filename, "%lld.fifo", cmbIcMsg.client_pid);
        pthread_t tid;
        pthread_create(&tid, NULL, server_thread, NULL);
    }
    return 0;
}

void * server_thread(void *)
{
    pthread_detach(pthread_self());
    if((fd2 = open(filename, O_WRONLY, 0)) < 0)
    {
        printf("Falied to open %s", filename);
        exit(-1);
    }
    sem_post(&main_sem);
    struct CMB cmbMsg;
    long long int sum = 0;
    while(true)
    {
        while(read(fd1, &cmbIcMsg, sizeof(struct CMB)) == 0);
        sum += cmbMsg.vector_atom;
        if(cmbMsg.EOV == true)
        {
            break;
        }
    }
    struct SMB smbMsg;
    smbMsg.suma = sum;
    write(fd2, &smbMsg, sizeof(struct SMB));
    return NULL;
}

0 个答案:

没有答案