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

2023-09-22 13:43:44

1.问题和解决方法

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

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

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

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

答:这是不正确的。

因为:如图所示:

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

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

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

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

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

2.复制文件描述符

#include<unistd.h>

int dup(
int fildes    //需要复制的文件描述符
);

int dup2(
int fildes,   //需要复制的文件描述符
int fildes2   //明确指定的文件描述符整数值
);

成功返回复制的文件描述符
失败返回-1

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

3.流的半关闭

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

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

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

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

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

更多推荐

智云谷再获AR HUD新项目定点,打开HUD出口海外新通道

深圳前海智云谷科技有限公司(以下简称“智云谷”)于近日收到国内某新能源车企的《定点通知书》,选择智云谷作为其新车型ARHUD开发与量产供应商。智云谷获得定点的车型为海外出口车型,该车型预计在2024年下半年量产。中国汽车全产业链出海“圈粉”随着中国新能源车的强势崛起,中国车企纷纷开始拓展海外市场。海关总署数据显示,今年

单点登录原理及JWT实现

单点登录原理及JWT实现一、单点登录效果首先我们看通过一个具体的案例来加深对单点登录的理解。案例地址:https://gitee.com/xuxueli0323/xxl-sso?_from=gitee_search把案例代码直接导入到IDEA中然后分别修改下server和samples中的配置信息在host文件中配置1

【C语言】结构体内存对齐机制详解

目录一、前言二、结构体内存对齐规则三、实例解析一、前言在讲解结构体内存对齐机制之前,我们先来看1个例子:typedefstruct{charsex;//性别intid;//学号charname[20];//姓名floatscore;//成绩charaddr[30];//地址}STU;intmain(){STUstude

LeetCode 27. 移除元素(JavaScript 简单)

1.题目给你一个数组nums和一个值val,你需要原地移除所有数值等于val的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用O(1)额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。说明:为什么返回数值是整数,但输出的答案是数组呢?请注意,输入数组是以「引用」

使用延迟队列解决分布式事务问题——以订单未支付过期,解锁库存为例

目录一、前言二、库存三、订单一、前言上一篇使用springcloud-seata解决分布式事务问题-2PC模式我们说到了使用springcloud-seata解决分布式的缺点——不适用于高并发场景因此我们使用延迟队列来解决分布式事务问题,即使用柔性事务-可靠消息-最终一致性方案(异步确保型)以下是下订单的代码//@Gl

ctfshow web入门(1)

web1查看页面源代码web2ctr+uweb3因为查看源码没有东西,网络查看下数据包,找到flagweb4robots协议其他都没啥信息,就看下robots.txt,这个文件可能会泄露部分网站目录访问下,看到了web5phps泄露也没啥信息,在响应头里面看到了X-Powered-By:PHP/7.3.11得知-网站是

Grom 如何解决 SQL 注入问题

什么是SQL注入SQL注入是一种常见的数据库攻击手段,SQL注入漏洞也是网络世界中最普遍的漏洞之一。SQL注入就是恶意用户通过在表单中填写包含SQL关键字的数据来使数据库执行非常规代码的过程。这个问题的来源就是,SQL数据库的操作是通过SQL命令执行的,无论是执行代码还是数据项都必须卸载SQL语句中,这就导致如果我们在

【操作系统笔记十二】Linux常用基础命令

Linux常用快捷键Tab命令或路径等的补全键,特别常用的快捷键Ctrl+insert复制命令行内容(常用可提高效率)Shift+insert粘贴命令行内容(常用可提高效率)Ctrl+C中断当前任务(退出)Ctrl+Z暂停当前任务Ctrl+I清除屏幕所有的内容Ctrl+A光标迅速回到行首Ctrl+E光标迅速回到行尾Ct

红 黑 树

文章目录一、红黑树的概念二、红黑树的实现1.红黑树的存储结构2.红黑树的插入一、红黑树的概念在AVL树中删除一个结点,旋转可能要持续到根结点,此时效率较低红黑树也是一种二叉搜索树,通过在每个结点中增加一个位置来存储红色或黑色,并对结点的着色进行限制,使得该二叉搜索树的最长路径不超过最短路径的两倍,即红黑树是一颗近似平衡

【postgresql】ERROR: column “xxxx.id“ must appear in the GROUP BY

org.postgresql.util.PSQLException:ERROR:column"xxx.id"mustappearintheGROUPBYclauseorbeusedinanaggregatefunction错误:列“XXXX.id”必须出现在GROUPBY子句中或在聚合函数中使用在mysql中是正常使用

【八大经典排序算法】冒泡排序

【八大经典排序算法】冒泡排序一、概述二、思路解读三、代码实现四、优化一、概述冒泡排序由于其简单和易于理解,使其成为初学者学习排序算法的首选,也是初学者接触到的第一个排序算法。其原理是通过重复交换相邻的元素来将最大的元素逐步“冒泡”到最后。冒泡排序由美国计算机科学家冯·诺伊曼(JohnvonNeumann)于1945年提

热文推荐