• [C++ 网络协议] I/O流分离所带来的半关闭问题


    1.问题和解决方法

    根据所学内容,I/O流分离现如今有如下2种方法:

            1.调用进程fork函数,分离出子进程,主进程和子进程分别进行输入流的读和输出流的写。

            2.用FILE指针按读模式和写模式将输入流和输出流进行区分。

    第一种方法,可以对输出流调用shutdown函数进行半关闭,从而不会影响到输入流接收客户端的数据,这是没问题的。但第二种方法,我们是不是也只要对FILE指针指向的写模式调用fclose函数,而读模式不调用fclose,是不是也可以实现半关闭?

    答:这是不正确的。

    因为:如图所示:

    读模式和写模式的FILE指针,都是通过同一个文件描述符调用fdopen函数所得来的,而对于两个模式的任意一个来说,只要调用了fclose函数,那么连同文件描述符,也会关闭掉,如图:

    所以,套接字会终止,则读模式FILE指针不能再读取任何数据了。

    所以这个问题应该怎么解决,我怎么样才能实现FILE指针读写模式的半关闭?

    答:很简单,复制这个文件描述符,让读模式的FILE指针和写模式的FILE指针分别对应一个即可,如图:

    这样的话,因为,销毁所有文件描述符后才能销毁套接字,所以,我们关闭了其中一个FILE指针也不会影响到另一个。

    2.复制文件描述符

    1. #include
    2. int dup(
    3. int fildes //需要复制的文件描述符
    4. );
    5. int dup2(
    6. int fildes, //需要复制的文件描述符
    7. int fildes2 //明确指定的文件描述符整数值
    8. );
    9. 成功返回复制的文件描述符
    10. 失败返回-1

    调用dup函数,不同于进程的fork函数,并不会创建新的进程,只是创建一个新的文件描述符,而这个文件描述符可以和原件同时访问文件的情况。当然,文件描述符的值不会重复

    3.流的半关闭

    1. readfp=fdopen(clnt_sock,"r");
    2. writefp=fdopen(dup(clnt_sock),"w"); //调用dup函数复制clnt_sock
    3. ......
    4. shutdown(fileno(writefp),SHUT_WR); //将writefp转换为文件描述符,再调用shutdown函数关闭
    5. fclose(writefp);
    6. ...... //接收客户端最后发送的消息

    首先,复制文件描述符,创建写模式FILE。

    其次,在结束使用后,先将FILE写模式转换为文件描述符,再调用shutdown函数半关闭掉,发送EOF给客户端。

    最后,调用fclose函数,关闭FILE写模式。

    注意,shutdown了文件描述符之后,仍然要fclose指定的FILE指针。

  • 相关阅读:
    接入 NVIDIA A100、吞吐量提高 10 倍!Milvus GPU 版本使用指南
    BASH shell脚本篇5——文件处理
    论文阅读CVPR2022 《Language As Queries for Referring Video Object Segmentation》
    OSINT技术情报精选·2024年6月第1周
    hadoop namenode -format报错显示:命令未找到
    MySQL数据库(表的CRUD基础操作(最常用))
    Linux | 进程
    Go语言中gin+gorm开发前端端分离博客时遇到的问题,gorm执行查询时如何选中特定字段?
    利用宝塔实现百度自动推送
    16. Go的目录和文件操作
  • 原文地址:https://blog.csdn.net/A_ns_wer_/article/details/133167100