学习fifo管道,对read的一点总结

本文通过实例探讨了在Unix网络编程中遇到的fifo管道问题。当server发送完文件内容,client会因read调用的阻塞特性而陷入死循环。解决方法包括通过特定协议告知传输结束,例如在server端发送'over'信号,或者子进程关闭writefd来使client的read调用返回。这种方式避免了由于FIFO没有文件结束符而导致的困扰。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


           按照unix网络编程第二版中的fifo管道例子,跑了一下,发现如下问题:

当server通过fifo管道把文件内容发传完给client后,client也正确接收完,server就退出,但client没退出,还在死循环????


原因:client中的read调用是阻塞的,不会主动退了, 所以一直在监测管道的数据到来(不像socket那样,一端关闭,另一端就会返回),其实它的确不知是否结束。

解决方法:要对方结束,就要在应用上处理,通过指定的协议,让对方知道传输己结束,修改后的client和server如下:


void client(int readfd, int writefd)
{
        size_t len;
        size_t n;
        char buf[100];

       fgets(buf, 100, stdin);
       len = strlen(buf);
       if ('\n' == buf[len -1])
       {
              len--;
       }

       write(writefd, buf, len);

       while( (n = read(readfd, buf, 100)) > 0 )
       {
        write(STDOUT_FILENO, buf, n);

        if ( strcmp(buf, "over") == 0 )
        {
              break;
        }
     }
     std::cout << "client while over" << std::endl;
}

void server(int readfd, int writefd)
{
    int fd;
    size_t n;
    char buf[100];

    if ((n = read(readfd, buf, 100)) == 0)
    {
        std::cout << "end-of-file while reading pathname" << std::endl;
    }
    buf[n] = '\0';

    if ((fd = open(buf, O_RDONLY)) < 0)
    {
        snprintf(buf + n, sizeof(buf) - n, ": can't open, %s\n", strerror(errno));
        n = strlen(buf);
        write(writefd, buf, n);
    }
    else
    {
        while ( (n = read(fd, buf, 100)) > 0 )
        {
            write(writefd, buf, n);
        }
        write(writefd, "over", 5);

        std::cout << "server while over" << std::endl;
        close(fd);
    }
}


================================================================================================================

往后的例子看到,更好的办法是:
        子进程把writefd关闭,这样父过程client中的read调用就会返回。


注UNPv2中4.10节:

        在使用管道或FIFO时,可以通过关闭IPC通道来通知对方己到达输入文件的结尾。不过我们通过发送回一个长度为0的消息来达到同样的目的,因为存在没有文件结束符概念的其他类型的IPC.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值