【问题标题】:client-server communication emulation in c using pipesc中使用管道的客户端 - 服务器通信仿真
【发布时间】:2022-11-26 14:09:55
【问题描述】:

我想使用进程间通信模拟机票预订系统管道专用

我想要 10 个与主服务器交互的客户端(父进程) 使用管道。

客户(子进程) 应该生成一个从 0-9 的随机数,它应该是航班号和 1-3 之间的座位数量。然后他们将在客户端传递上述请求,经过一些检查后,他们将被告知是否服务器可以容纳他们的座位(成功/失败).

我这里的问题是 10 个子进程确实生成随机航班 ID 和座位号,但父程序只会保留第一个生成的航班 ID10倍.

这是我第一次使用管道和文件描述符,所以可能会有很多错误,如果你能发现它们并帮助我解决这个问题,将不胜感激!

如果您需要对任何命令的进一步解释,请告诉我,我使用很多变量来进行求和和检查。(这只是与 IPC 相关的程序的一部分,如果您希望我编辑完整的程序,请与我联系)

for(j=0;j<=9;j++)
{
    pid=fork();
    if(pid<0)
    {
        perror("Error");
        exit(1);
    }
    if(pid==0)
    {
        for(i=0;i<=9;i++)
        {
            close(fd1[j][0]);
            close(fd2[j][0]);
            seats = (rand() % 3)+1 ;
            id= (rand()% 10);
            printf("id %d seats %d\n",id,seats);
            write(fd1[j][1],&id,sizeof(id));
            write(fd2[j][1],&seats,sizeof(seats));
            close(fd1[j][1]);
            close(fd2[j][1]);
            read(fd1[j][0],&good,sizeof(good));
            if(good)
            {
                printf("success\n");
                read(fd2[j][0],&flights[id].price,sizeof(flights[id].price));
                close(fd2[j][0]);
            }
            else
            {   
                printf("failure\n");
            }
            close(fd1[j][0]);}
        exit(EXIT_FAILURE);
    }
    else
    {
        if(check==0){
            struct fl flights[10]= 
            {
                {0,(rand() % 5)+1,"Athens","Paris",20},
                {1,(rand() % 5)+1,"London","Madrid",25},
                {2,(rand() % 5)+1,"Moscow","Kiev",17},
                {3,(rand() % 5)+1,"Manchester","Munchen",23},
                {4,(rand() % 5)+1,"Budapest","Torino",15},
                {5,(rand() % 5)+1,"Rome","Thessaloniki",21},
                {6,(rand() % 5)+1,"Amsterdam","Lisbon",13},
                {7,(rand() % 5)+1,"Sofia","Tallinn",10},
                {8,(rand() % 5)+1,"Vienna","Bucharest",22},
                {9,(rand() % 5)+1,"Copenhagen","Minsk",26}
            }; 
            check=1;}
        for(j=0;j<=9;j++)
        {
            close(fd1[j][1]);
            close(fd2[j][1]);
            read(fd1[j][0],&id,sizeof(id));
            read(fd2[j][0],&seats,sizeof(seats));
            sun_krathseis=sun_krathseis+1;
            sunolikes[id]=sunolikes[id]+1;
            if(flights[id].available_seats>=seats)
            {
                kerdh=kerdh+flights[id].price;
                flights[id].available_seats=flights[id].available_seats-seats;
                epit[id]=epit[id]+1;
                epitux_krat=epitux_krat+1;
                good=1;
            }
            else
            {
                apot[id]=apot[id]+1;
                good=0;
            }
            write(fd1[j][1],&good,sizeof(good));
            if(good){
                write(fd2[j][1],&flights[id].price,sizeof(flights[id].price));
                close(fd2[j][1]);
            }
            close(fd1[j][1]);  
        }
        waitpid=wait(NULL);
        if(waitpid==-1)
        {
            perror("Error");
        }
        printf("Parent proccess ended \n");
    }
}

}

【问题讨论】:

  • 孩子似乎在循环的第一次迭代中关闭了 fds。如果他们已经关闭,他们不能在第二次迭代中写信给他们!将错误检查添加到 writes,您可能会看到 invalid file descriptor 错误。
  • 但....?为什么孩子在循环的第一次迭代中退出?如果您在第一次迭代中退出,那么循环有什么意义?你的逻辑有些奇怪。
  • 可能是我眼睛瞎了,但是for() { ... } else {}是个语法错误。如果您使用更具可读性的缩进样式,将会有所帮助。单空格缩进不是一个好主意。
  • 所以我应该避免关闭孩子的 fds?哪些 fds 是读的还是写的?
  • 如果子进程向父进程写入,则子进程关闭读端并保持写端打开。

标签: c


【解决方案1】:

@GENERALE 我想知道我是否可以获得与 IPC 关联的完整程序?这真的对我有很大帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    • 2020-08-04
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    相关资源
    最近更新 更多