有关fgets和fcntl的讨论-待整理更新
问题引出
一个client程序:select 超时监听 sockfd套接字 和 STDIN_FILENO标准输入:若sockfd可读则接收server报文;若标准输入可读(按下回车),则开始用fgets/fscanf等函数从标准输入捕获字符后发送给server;若select 2秒超时,client发送一次心跳包给server。要求不能开其他的进程或线程,也不能使用定时器和信号,即单线程client。
现在问题来了,在使用fgets/fscanf时,会阻塞select函数,这样一来client就无法进入超时流程发送心跳包;若将标准输入设置为非阻塞,那么fgets/fscanf立即返回,捕获的内容为空,达不到要求。
请问,有没有一种方法能让程序一边等待fgets/fscanf的捕获,一边循环非阻塞执行select函数?
尝试方法
Method1
用过linux下实现的kbhit,若没有按键输入则跳出这个函数,有输入则getchar到一个数组中存放然后退出函数,若捕获到回车键再把数组内容填充到发送报文。这样就是一个非阻塞的输入函数。
case1:select还是监听标准输入,只有按下回车键,程序才可能进入select的标准输入可读流程。这样要想输入一个字符必须先敲一个回车,显然不行。
case2:select不监听标准输入,在循环中,先执行select,再执行kbhit。这种方式能行,但是响应太慢,因为select是2秒超发心跳,所以select是半阻塞的,也就是说要想执行kbhit,必须等待2秒。
最终放弃此方法。
- //示例代码
- #include <stdio.h>
- #include <fcntl.h>
- #include <termios.h>
- int kbhit(void) //return 0: no keyboard hit; return 1: keyboard hit
- {
- struct termios oldt, newt;
- int ch;
- int oldf;
- tcgetattr(STDIN_FILENO, &oldt);
- newt = oldt;
- newt.c_lflag &= ~(ICANON | ECHO);
- tcsetattr(STDIN_FILENO, TCSANOW, &newt);
- oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
- fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
- ch = getchar();
- tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
- fcntl(STDIN_FILENO, F_SETFL, oldf);
- if(ch != EOF)
- {
- ungetc(ch, stdin);
- return 1;
- }
- return 0;
- }
- int main()
- {
- unsigned char line[128] = {0};
- unsigned char ch;
- unsigned int i = 0;
- while(1)
- {
- task_1(); //其它任务
- if(kbhit()) { //有键按下
- if((ch = getchar() != 0x0a) { //回车键没按下
- line[i++] = ch;
- } else { //回车键按下
- memset(line, 0, 128);
- i = 0;
- task_2(); //此处解析line数组内容
- }
- }
- }
- return 0;
- }
Method2
在进行select循环之前就把要输入的内容提前录入,然后回车。之后程序进入到select的标准输入可读流程,在这里使用fgets将之前录入的内容全部读入一个buf[],然后解析字符串,填入到发送报文;即只要不输入回车键,程序就无法进入select的标准输入可读流程,自然不会影响2秒超时发保活包。
这种方法实验效果能达到题目要求。
Method3
fgets为行缓存IO函数,遇到回车键才把处理缓冲中的数据流。将标准输入流stdin改为无缓冲方式,这样只要有字符敲入(即使没有敲入回车)select就会监听到标准输入可读。在相应流程中使用getchar()将捕获的输入存放于buf[],然后退出流程继续监听。若捕获到0x0a,表明输入的结束,之后同方法2一样解析和发送。
这种方法实验效果也能达到题目要求。
- setvbuf(stdin, NULL, _IONBF, 0); //设置标准输入流为无缓存
有关fgets和fcntl的讨论-待整理更新的更多相关文章
- Python面试题整理-更新中
几个链接: 编程零基础应当如何开始学习 Python ? - 路人甲的回答 网易云课堂上有哪些值得推荐的 Python 教程? - 路人甲的回答 怎么用最短时间高效而踏实地学习 Python? - 路 ...
- Beta 讨论分析——持续更新ing
wonderland Beta 讨论分析 标签(空格分隔): 软工实践 wonderland 主要工作: info信息: 1.关联账号界面:hbb 2.标签检索界面:hbb 3.近期活跃度(cf.hd ...
- JS-JavaScript类库整理 [更新中...]
老大.jQuery插件库 ——收集最全最新最好的jQuery插件 http://www.jq22.com/ 一.Moment.js ——JavaScript 日期处理类库 http://momentj ...
- markdown常用命令(持续整理更新...)
编写使用的工具 VS Code 拥有丰富插件支持的代码编辑器,当然也支持markdown MdEditor一款在线编辑markdown网站 1.标题 示例: # 一级标题 ## 二级标题 ### 三级 ...
- 前端开发常用PhotoShop快捷键整理(更新中)
图片来源 UI提供的psd图 印屏幕:PrScrn SysRq(键盘按键) 浏览器(插件)获取 常用的快捷键: 新建 Ctrl + N 取消选框 Ctrl + D 反选 Ctrl + shift + ...
- IdentityServer4笔记整理(更新中)
1 OAuth 2.0 1.1 OAuth 2.0协议流程图 1.2 授权码模式 1.3 简化模式 1.4 资源所有者密码模式 1.5 客户端凭证模式 2 OpenID Connect(OIDC) 2 ...
- JavaEE error整理(不断更新)
该文章用于整理开发中遇到的一些错误,及解决方法,不断整理更新. 1. 缺包异常 异常1:java.lang.NoClassDefFoundError: org/apache/commons/loggi ...
- TypeScript 基础知识点整理
一.TypeScript的特点 1.支持ES6规范 2.强大的IDE支持(集成开发环境) 允许为变量指定类型,减少你在开发阶段犯错误的几率. 语法提示,在IDE编写代码时,它会根据你所处的上下文把你能 ...
- 重新整理 mysql 基础篇————— 介绍mysql[一]
前言 准备整理mysql的基础篇了,前面整理了sql语句序列的的<sql 语句系列(八百章)>,感觉很多用不上,就停下来了,后续还是会继续整理. mysql 基础篇主要是对一些基础进行整理 ...
随机推荐
- Java(25-40)【数据类型转换、运算符、方法入门】
1.ASCII编码表 0--48 A--65 a--97 2. Unicode万国码 字符'中'为20013 3.算数运算符 double类型的加上int类型结果为double byte short ...
- python读取excel数据为json格式(兼容xls\xlsx)
做自动化时需要从excel读取数据: 本文实现将excel文件数据读取为json格式,方便自动化调用 读取xls文件 使用xlrd读取xls文件代码: import xlrd def read_xls ...
- 前端缓存API请求数据
1. 背景 在一些项目中,有时候会出现不同模块重复请求大量相同api接口的情况,特别是在一些功能相似的后台管理页面中.以下面这几个页面为例,每次进入页面都需要请求等大量重复的下拉框数据,下拉框数据短时 ...
- kubernetes集群证书更新
kubeadm 默认证书为一年,一年过期后,会导致api service不可用,使用过程中会出现:x509: certificate has expired or is not yet valid. ...
- python set 一些用法
add(增加元素) name = set(['Tom','Lucy','Ben']) name.add('Juny') print(name)#输出:{'Lucy', 'Juny', 'Ben', ' ...
- 算法tip:栈的可生成性问题
算法tip:栈的可生成性问题 问题描述 给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,判断它们是否可以在最初空栈上进行推入 push 和弹出 pop 操作.(LeetCod ...
- MySQL查询日志介绍
MySQL查询日志介绍 MySQL的查询日志记录了所有MySQL数据库请求的信息.无论这些请求是否得到了正确的执行.默认文件名为hostname.log.默认情况下MySQL查询日志是关闭的.生产环境 ...
- POJ 3301 三分(最小覆盖正方形)
题意: 给你n个点,让你找一个最小的正方形去覆盖所有点.思路: 想一下,如果题目中规定正方形必须和x轴平行,那么我们是不是直接找到最大的x差和最大的y差取最大就行了,但是这个题目 ...
- Python简易远控(单线程版)
1. 技术:管道通信,流文件处理,socket基础 2. Tips: 默认IP:127.0.0.1 默认端口:7676 3. 代码样例: 服务端: #!/usr/bin/env python # en ...
- hdu1568斐波那契前4位
题意: 就是求斐波那契数,但是只要求输出前四位,(n<=100000000). 思路: 这个要用到斐波那契的公式和一些log的规律,直接打看着很乱,直接在网上偷张图片吧: ...