unix网络编程 str_cli epoll 非阻塞版本

unix网络编程 str_cli epoll 非阻塞版本

unix网络编程str_cli使用epoll实现讲了使用epoll配合阻塞io来实现str_cli,这个版本是配合非阻塞io.
可以看到采用非阻塞io以后复杂度大大提升了. 这个版本是在原书select版本基础之上修改而来,可以看出epoll又比select版本复杂了很多,每次都需要调用epoll_ctl三次,效率肯定比select还低.

存在一个问题!!就是epoll_wait对于重定向的stdin,始终阻塞,不晓得什么原因,以后再研究吧!

因为不能重定向stdin所以也不能测试性能,只能说是可以工作.

/* include nonb1 */
#include    "../lib/unp.h"
#include <sys/epoll.h>
//epoll 非阻塞io, 采用了非阻塞io以后性能得到大幅提升,但是复杂度也飞速提升。//确保events有足够的空间,这里足够了
//添加一个事件到队列中,可能会改变数组中的epoll_event数量。
static uint32_t addEvents(struct epoll_event * events,uint32_t nfds,int fd,uint32_t event){int i=0;for(i=0;i<nfds;i++){if(events[i].data.fd==fd){events[i].events|=event;}}if(i==nfds){events[i].data.fd=fd;events[i].events=event;nfds++;}return nfds;
}
#define VOL2
void str_cli(FILE *fp, int sockfd)
{int         val,stdineof=0;ssize_t     n, nwritten;char        to[MAXLINE], fr[MAXLINE];char        *toiptr, *tooptr, *friptr, *froptr;struct epoll_event event;struct epoll_event events[20];int i,efd,nfds;int noevent=0;val = Fcntl(sockfd, F_GETFL, 0);Fcntl(sockfd, F_SETFL, val | O_NONBLOCK);val = Fcntl(STDIN_FILENO, F_GETFL, 0);Fcntl(STDIN_FILENO, F_SETFL, val | O_NONBLOCK);val = Fcntl(STDOUT_FILENO, F_GETFL, 0);Fcntl(STDOUT_FILENO, F_SETFL, val | O_NONBLOCK);toiptr = tooptr = to;   /* initialize buffer pointers */friptr = froptr = fr;stdineof = 0;efd = epoll_create (10);if(efd<0){err_sys("epoll create failed");}event.data.fd=fileno(fp);event.events=EPOLLIN;epoll_ctl(efd,EPOLL_CTL_ADD,fileno(fp),&event);event.data.fd=sockfd;event.events=EPOLLIN;epoll_ctl(efd,EPOLL_CTL_ADD,sockfd,&event);event.data.fd=STDOUT_FILENO;event.events=EPOLLOUT;epoll_ctl(efd,EPOLL_CTL_ADD,STDOUT_FILENO,&event);for ( ; ; ) {event.data.fd = fileno(fp);event.events = 0;//fprintf(stderr, "tooptr=0x%x,toiptr=0x%x,froptr=0x%x,friptr=0x%x \n", tooptr, toiptr, froptr, friptr);if (stdineof == 0 && toiptr < &to[MAXLINE]) //并不能确定在不在里面,多做一次不是坏事{event.events = EPOLLIN;epoll_ctl(efd, EPOLL_CTL_MOD, fileno(fp), &event); //read from stdin}elseepoll_ctl(efd, EPOLL_CTL_MOD, fileno(fp), &event);event.data.fd = sockfd;event.events = 0;if (friptr < &fr[MAXLINE])event.events |= EPOLLIN;            /* read from socket */if (tooptr != toiptr)event.events |= EPOLLOUT;            /* data to write to socket */epoll_ctl(efd, EPOLL_CTL_MOD, sockfd, &event);event.data.fd = STDOUT_FILENO;event.events = 0;if (froptr != friptr) {event.events = EPOLLOUT;epoll_ctl(efd, EPOLL_CTL_MOD, STDOUT_FILENO, &event);    /* data to write to stdout */}else {epoll_ctl(efd, EPOLL_CTL_MOD, STDOUT_FILENO, &event);}nfds = epoll_wait(efd, events, sizeof(events) / sizeof(struct epoll_event), -1);//fprintf(stderr, "nfds return:%d, %d,0x%x,sockfd=%d\n", nfds, events[0].data.fd, events[0].events, sockfd);startloop:for (i = 0; i < nfds; i++) {if (events[i].data.fd == STDIN_FILENO && events[i].events != 0) {events[i].events = 0; //清除处理过的事件if ((n = read(STDIN_FILENO, toiptr, &to[MAXLINE] - toiptr)) < 0) {if (errno != EWOULDBLOCK)err_sys("read error on stdin");} else if (n == 0) {
#ifdef    VOL2fprintf(stderr, "%s: EOF on stdin\n", gf_time());
#endifstdineof = 1;            /* all done with stdin */if (tooptr == toiptr)Shutdown(sockfd, SHUT_WR);/* send FIN */} else {
#ifdef    VOL2fprintf(stderr, "%s: read %d bytes from stdin\n", gf_time(), n);
#endiftoiptr += n;            /* # just read */int ret2=addEvents(events, nfds, sockfd, EPOLLOUT);if(ret2!=nfds){nfds=ret2;goto startloop;}}}if (events[i].data.fd == sockfd && events[i].events != 0) {if (events[i].events & EPOLLIN) {printf("read socket\n");if ((n = read(sockfd, friptr, &fr[MAXLINE] - friptr)) < 0) {printf("read socket error");if (errno != EWOULDBLOCK)err_sys("read error on socket");} else if (n == 0) {
#ifdef    VOL2fprintf(stderr, "%s: EOF on socket\n", gf_time());
#endifif (stdineof)return;        /* normal termination */elseerr_quit("str_cli: server terminated prematurely");} else {
#ifdef    VOL2fprintf(stderr, "%s: read %d bytes from socket\n",gf_time(), n);
#endiffriptr += n;        /* # just read */int ret2 = addEvents(events, nfds, STDOUT_FILENO, EPOLLOUT);/* try and write for next loop */if(ret2!=nfds){nfds=ret2;events[i].events&=~EPOLLIN; //清除已经处理过的in事件goto startloop;}}}if (events[i].events & EPOLLOUT) {if ((n = toiptr - tooptr) > 0) {if ((nwritten = write(sockfd, tooptr, n)) < 0) {if (errno != EWOULDBLOCK)err_sys("write error to socket");} else {
#ifdef    VOL2fprintf(stderr, "%s: wrote %d bytes to socket\n",gf_time(), nwritten);
#endiftooptr += nwritten;    /* # just written */if (tooptr == toiptr) {toiptr = tooptr = to;    /* back to beginning of buffer */if (stdineof)Shutdown(sockfd, SHUT_WR);    /* send FIN */}}}}events[i].events = 0; //清除处理过的事件}if (events[i].data.fd == STDOUT_FILENO) {if ((n = friptr - froptr) > 0) {if ((nwritten = write(STDOUT_FILENO, froptr, n)) < 0) {if (errno != EWOULDBLOCK)err_sys("write error to stdout");} else {
#ifdef    VOL2fprintf(stderr, "%s: wrote %d bytes to stdout\n",gf_time(), nwritten);
#endiffroptr += nwritten;        /* # just written */if (froptr == friptr)froptr = friptr = fr;    /* back to beginning of buffer */}}}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/459160.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java ee 指南 pdf_Java EE 7权威指南:卷1(原书第5版) 中文pdf

资源名称&#xff1a;Java EE 7权威指南&#xff1a;卷1(原书第5版) 中文pdf第一部分 引言第1章 概述 2第2章 使用教程示例 27第二部分 平台基础知识第3章 资源创建 38第4章 注入 41第5章 打包 44第三部分 Web层第6章 Web应用入门 50第7章 JSF技术 66第8章 Facelets…

中兴面试题2

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** from&#xff1a;http://blog.csdn.net/eddy_0825/article/details/1875566 现在的公司…

java 路径获取文件名称_java 根据文件获取文件名及路径的方法

filelistnew HashMap();/*** 递归方法* param path 文件路径*/public static void find(String path){File filenew File(path);File[] files file.listFiles();//如果文件数组为null则返回if (files null)return;for (int i 0; i < files.length; i) {if (files[i].isDi…

PYTHON招聘需求与技能体系

为什么80%的码农都做不了架构师&#xff1f;>>> 目前国内的招聘Python&#xff0c;基本都是偏向web后台开发&#xff0c;偶有高大上的数据挖掘&机器学习 这是之前(2012年)找工作整理的一些JD&#xff0c;在梳理几年来的笔记&#xff0c;顺带理一理 可以以此建…

C#学习笔记(十一):动态类型

C#是一门静态类型的语言&#xff0c;但是在C#4.0时微软引入了动态类型的概念。 dynamic 关键字dynamic用来定义动态对象&#xff0c;我们来看一下动态类型的一些特性。 调用不同类的相同方法 我们有两个或多个不相关的类&#xff0c;然后运行时需要可以调用到相同名称的方法&am…

c++面试试题

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** from&#xff1a;http://blog.csdn.net/eddy_0825/article/details/1875597 1 …

《FPGA全程进阶---实战演练》第二十一章 电源常用类型:LDO和 DCDC

高速电路中的电源设计 高速电路中的电源设计大概分为两种&#xff0c;一种是集总式架构&#xff0c;一种是分布式架构。集总式架构就是由一个电源输入&#xff0c;然后生成多种所需要的电压。如图1所示。这种架构会增加多个DC/DC模块&#xff0c;这样成本不可控&#xff0c;PCB…

自定义View控件(2—手写实例代码)

1、 步骤: 1.自定义一个类继承于UIView 2.在initWithFrame方法中添加子控件 3.在layoutSubviews中设置子控件的位置 4.提供一个属性保存外界传入的数据(模型对象), 重写setter方法设置子控件的数据 - 类工厂方法(便利构造器) 按照苹果的风格和规范, 一般情况一个用于创建对…

pojo java_Java——POJO总结

一&#xff1a;什么是POJO“Plain Old Java Object”“简单java对象”。POJO的内在含义是指那些没有从任何类继承、也没有实现任何接口&#xff0c;更没有被其它框架侵入的java对象。二&#xff1a;为什么会有POJO&#xff1f;主要是Java的开发者被EJB的繁杂搞怕了&#xff0c;…

MATLAB调用C/C++函数的方法

http://item.taobao.com/item.htm?spma1z10.5-c.w4002-9510581626.24.ZO6sko&id43401674106 精通MATLAB混合编程视频讲解 MATLAB各类函数视频讲解 基于MATLAB的高等数学问题求解 MATLAB函数速查视频讲解 面向对象C视频教程 精通MATLAB混编编程demo及PDF QQ&#xff1a…

迁云架构实践

本文着笔介绍IT互联网化为传统企业带来的技术挑战&#xff0c;并对上云架构最佳实践进行了深入介绍&#xff0c;首发于阿里云&《程序员》联合出品的《凌云》杂志。 作者&#xff1a; 王宇德&#xff0c;张文生 云计算作为信息技术领域的一种创新应用模式&#xff0c;自其诞…

最短路最新心得

如果&#xff0c;上面的图&#xff0c;如果用dij算法&#xff0c;那么dist[4] 4, 是得不到正确的结果的&#xff0c; 这个因为dist[3]先被确定是最小&#xff0c;然后用来更新dist[4] 但是存在负权&#xff0c;使得dist[3]更小&#xff0c;但是我们已经把结点3标记为不可用了…

java canvas 缩放图片_java-GWT:放大和缩小画布绘图

我想应用放大和缩小,并在画布上重新绘制对象,以便在最大和最小缩放级别都能获得清晰的视图.我获得了如何执行操作的参考here,因此我已将画布传递给可缩放图像构造函数而不是图像,并按照所有步骤进行操作.我再次在“ mainDraw”方法中重画对象,但没有得到正确的结果.我知道我缺少…

MATLAB中MEX文件的编写与调试

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com http://item.taobao.com/item.htm?spma1z10.5-c.w4002-9510581626.24.ZO6sko&id43401674106 精通MATLAB混合编程视频讲解 MATLAB各类函数…

数据库设计思考

一&#xff1a;没有完美的数据库设计&#xff0c;只有符合业务的数据库设计&#xff01; 二&#xff1a;我们的数据库设计&#xff0c;在遵守标准&#xff08;三大范式&#xff09;的同时也要考虑客户的体验&#xff01; 有用户才有天下&#xff01; 三&#xff1a;数据库设计时…

performSegueWithIdentifier:sender里边的sender是啥意思

performSegueWithIdentifier:sender里边的sender是啥意思啊&#xff1f;怎样用啊&#xff1f; [self performSegueWithIdentifier:"pushSign" sender:self]; [self performSegueWithIdentifier:"pushSign" sender:sender]; [self performSegueWithIdent…

java wrapper怎么运行_如何从智能合约中生成Java Wrapper

在本文中&#xff0c;我们将了解如何直接从智能合约生成Java Wrapper类以与Java中的智能合约进行交互。从智能合约生成Java Wrapper类有不同的方法&#xff1a;1. Web3j命令行工具和solc2. Web3j命令行工具和Truffle构建生成的工件3. web3j-maven-plugin4. web3j-gradle-plugin…

Hive 1.2.1SparkSqoop安装指南

目录 目录 1 1. 前言 1 2. 约定 2 3. 服务端口 2 4. 安装MySQL 2 4.1. 安装MySQL 2 4.2. 创建Hive元数据库 4 5. 安装步骤 5 5.1. 下载Hive 1.2.1二进制安装包 5 5.2. 安装Hive 5 5.3. 安装MySQL-Connector 5 5.4. 修改配置 5 5.4.1. 修改/etc/profile或~/.profile 5 5.4.2. 修…

Matlab与C/C++混合编程调用OpenCV

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com http://item.taobao.com/item.htm?spma1z10.5-c.w4002-9510581626.24.ZO6sko&id43401674106 精通MATLAB混合编程视频讲解 MATLAB各类函数…

STL--排序与检索

题目 现有N个大理石&#xff0c;每个大理石上写了一个非负整数。首先把各数从小到大排序&#xff0c;然后回答Q个问题。每个问题是否有一个大理石写着某个整数x,如果是&#xff0c;还要回答哪个大理石写着x。排序后的大理石从左到右编写为1-N。&#xff08;样例中&#xff0c;…