Linux 网络编程 epoll中的EPOLLIN EPOLLOUT如何触发

代码很长只截取关键部分
//服务器端
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include"locker.h"
#include"threadpool.h"
#include"http_conn.h"
#include"http_conn.cpp"
extern void addfd(int epollfd,int fd,bool one_shot);
extern void removefd(int epollfd,int fd);
#define MAX_FD 65536
#define MAX_EVENT_NUMBER 10000
void addsig(int sig,void(handler)(int),bool restart=true)
{
struct sigaction sa;
memset(&sa,'\0',sizeof(sa));
sa.sa_handler=handler;
if(restart)
{
sa.sa_flags|=SA_RESTART;
}
sigfillset(&sa.sa_mask);
assert(sigaction(sig,&sa,NULL)!=-1);
}

void show_error(int connfd,const char* info)
{
printf("%s",info);
send(connfd,info,strlen(info),0);
close(connfd);
}
int main(int argc,char* argv[])
{
if(argc {
printf("usage: %s ip_address port_number\n",basename(argv[0]));
return 1;
}
const char* ip=argv[1];
int port=atoi(argv[2]);
addsig(SIGPIPE,SIG_IGN);
threadpool* pool=NULL;

pool=new threadpool<http_conn>(3);

http_conn* users=new http_conn[MAX_FD];
assert(users);
int user_count=0;
int listenfd=socket(PF_INET,SOCK_STREAM,0);
assert(listenfd>=0);
struct linger tmp={1,0};
setsockopt(listenfd,SOL_SOCKET,SO_LINGER,&tmp,sizeof(tmp));

int ret=0;
struct sockaddr_in address;
bzero(&address,sizeof(address));
address.sin_family=AF_INET;
inet_pton(AF_INET,ip,&address.sin_addr);
address.sin_port=htons(port);

ret=bind(listenfd,(struct sockaddr*)&address,sizeof(address));
assert(ret>=0);

ret=listen(listenfd,5);
assert(ret>=0);

epoll_event events[MAX_EVENT_NUMBER];
int epollfd=epoll_create(5);
assert(epollfd!=-1);
addfd(epollfd,listenfd,false);
http_conn::m_epollfd=epollfd;
while(1)
{
    int number=epoll_wait(epollfd,events,MAX_EVENT_NUMBER,-1);
    printf("number is %d\n",number);
    if((number<0)&&(errno!=EINTR))
    {
        printf("epoll failure\n");
        break;
    }
    for(int i=0;i<number;i++)
    {
        int sockfd=events[i].data.fd;
        if(sockfd==listenfd)
        {
            struct sockaddr_in client_address;
            socklen_t client_addrlength=sizeof(client_address);
            int connfd=accept(listenfd,(struct sockaddr*)&client_address,&client_addrlength);
            if(connfd<0)
            {
                printf("errno is: %d\n",errno);
                continue;
            }
            if(http_conn::m_user_count>=MAX_FD)
            {
                show_error(connfd,"Internal sever busy");
                continue;
            }
            printf("running the init(connfd,client_address)"\n);
            users[connfd].init(connfd,client_address);

        }
        else if(events[i].events&(EPOLLRDHUP|EPOLLHUP|EPOLLERR))
        {
            users[sockfd].close_conn();
        }
        else if(events[i].events&EPOLLIN)
        {
            if(users[sockfd].read())
            {
                pool->append(users+sockfd);
            }
            else
            {
                users[sockfd].close_conn();
            }
        }
        else if(events[i].events&EPOLLOUT)
        {
            if(!users[sockfd].write())
            {
                users[sockfd].close_conn();
            }
        }
    }
}
close(epollfd);
close(listenfd);
delete [] users;
delete pool;
return 0;

}

以上是服务器端的主程序 思路是epoll_wait接收到连接就为连接创建一个users存储然后等待后续的操作 但后面EPOLLIN 和EPOLLOUT永远都没法触发 不清楚该怎么触发 另一端写了服务器压力测试程序 和以上代码类似 就是循环创建socket对象然后connect()服务器 但我本意想两端互相发送数据 可connect()后服务器收到创建一个user 继续循环等待 但压力测试程序也在创建完对象后陷入循环等待服务器端的操作 请问该如何触发EPOLLIN和EPOLLOUT信号

以下是压力测试程序关键代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static const char* request = "GET http://localhost/index.html HTTP/1.1\r\nConnection: keep-alive\r\n\r\nxxxxxxxxxx";
int setnonblocking(int fd)
{
int old_option=fcntl(fd,F_GETFL);
int new_option=old_option|O_NONBLOCK;
fcntl(fd,F_SETFL,new_option);
return old_option;
}
void addfd(int epollfd,int fd)
{
epoll_event event;
event.data.fd=fd;
event.events=EPOLLIN|EPOLLET|EPOLLRDHUP;
epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event);
setnonblocking(fd);
}

bool write_nbytes(int sockfd,const char* buffer,int len)
{
int byters_write=0;
printf("write out %d bytes to socket %d\n",len,sockfd);
while(1)
{
bytes_write=send(sockfd,buffer,len,0);
if(bytes_write==-1)
{
return false;
}
else if(bytes_write==0)
{
return false;
}
len-=bytes_write;
buffer=buffer+bytes_write;
if(len<=0)
{
return true;
}
}
}

bool read_once(int sockfd,char* buffer,int len)
{
int bytes_read=0;
memset(buffer,'\0',len);
bytes_read=recv(sockfd,buffer,len,0);
if(bytes_read==-1)
{
return false;
}
else if(bytes_read==0)
{
return false;
}
printf("read in %d bytes from socket %d with content: %s\n",bytes_read,sockfd,buffer);
return true;
}
void start_conn(int epoll_fd,int num,const char* ip,int port)
{
int ret=0;
struct sockaddr_in address;
bzero(&address,sizeof(address));
address.sin_family=AF_INET;
inet_pton(AF_INET,ip,&address.sin_addr);
address.sin_port=htons(port);

for(int i=0;i<num;++i)
{
    sllep(1);
    int sockfd=socket(PF_INET,SOCK_STREAM,0);
    printf("create 1 sock\n");
    if(sockfd<0)
    {
        continue;
    }
    if(connect(sockfd,(struct sockaddr*)&address,sizeof(address))==0)
    {
        printf("build connection %d\n",i);
        addfd(epoll_fd,sockfd);
    }
}

}
void close_conn(int epoll_fd,int sockfd)
{
epoll_ctl(epoll_fd,EPOLL_CTL_DEL,sockfd,0);
close(sockfd);
}

int main(int argc,char* argv[])
{
assert(argc==4);
int epoll_fd=epoll_create(100);
start_conn(epoll_fd,atoi(argv[3]),argv[1],atoi(argv[2]));
epoll_event events[10000];
char buffer[2048];

while(1)
{
    int fds=epoll_wait(epoll_fd,events,10000,2000);
    for(int i=0;i<fds;i++)
    {
        int sockfd=events[i].data.fd;
        if(event[i].events&EPOLLIN)
        {
            if(!read_once(sockfd,buffer,2048));
            {
                close_conn(epoll_fd,sockfd);
            }
            struct epoll_event event;
            event.events=EPOLLOUT|EPOLLET|EPOLLERR;
            event.data.fd=sockfd;
            epoll_ctl(epoll_fd,EPOLL_CTL_MOD,sockfd,&event);
        }
        else if(events[i].events&EPOLLOUT)
        {
            if(!write_nbytes(sockfd,request,strlen(request)))
            {
                close_conn(epoll_fd,sockfd);
            }
            struct epoll_event event;
            event.events=EPOLLIN|EPOLLET|EPOLLERR;
            event.data.fd=sockfd;
            epoll_ctl(epoll_fd,EPOLL_CTL_MOD,sockfd,&event);
        }
        else if(events[i].events&EPOLLERR)
        {
            close_conn(epoll_fd,sockfd);
        }
    }
}

}

1个回答

你的得先注册事件监听啊。把要监控的套接字和要监听的事件注册

geqiandebei
千山~ 之前用EPOLL的时候,因为没初始化清空结构体吃了些亏,建议你在用 epoll_event之前都先用memset清下试试。。。
大约 4 年之前 回复
geqiandebei
千山~ 回复c5395348: 有连接请求和报文上来都是会出发EPOLLIN
大约 4 年之前 回复
c5395348
c5395348 注册了的 测试程序新建socket都能连接到服务器 但后续的EPOLLIN等事件无法触发 我想知道哪些操作会产生EPOLLIN和EPOLLOUT信号使得epoll_wait()函数能接收到
大约 4 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
Linux网络编程 epoll中EPOLLIN EPOLLOUT信号无法触发
-
Linux epoll 使用过程中的疑问,请专家给予指点一下
-
java nio的select和linux的epoll有什么区别?
-
linux如何采用epoll模型?就是我要改哪个地方才可以用这种模型了呢~
-
linux epoll_wait 监听管道读写事情,为什么管道退出,仍有事件发生
-
Linux下epoll并发数量达到1987个后涨不上去
-
关于epoll的问题,发送缓冲区以及接受缓冲区?
-
有关epoll的具体应用问题
-
Linux 环境下 无法加载 libnetty-transport-native-epoll.so
-
epoll写聊天程序 如何实现非阻塞通信
-
使用epoll出现问题,偶然性,有时候有问题,有时候又是正常的。
-
nginx或一些其他软件是如何使用同步的EPOLL实现异步非阻塞的?
-
单线程epoll的瓶颈在哪里,如何进一步提升?
-
epoll编程,困扰了我6年的问题!求讨论。
-
关于epoll返回值的问题
-
c++,epoll,线程池,求解
-
处理EPOLLIN事件 recv MSG_PEEK 返回 EAGAIN
-
linux服务器开发问题
-
epoll异步服务端程序,客户端采用多线程访问,服务端总是返回errno 9和107
-
程序员竟然钟爱这个!我 low了
今天和一帮程序员大佬群里闲聊(需要入群的可以加最底下微信哦~)聊着聊着竟然扯到鞋子一直在讨论穿什么鞋子比较耐脏然后一帮大佬集中围殴小白鞋说小白鞋虽然百搭但是太容易脏,太不...
程序员实用工具网站
目录 1、搜索引擎 2、PPT 3、图片操作 4、文件共享 5、应届生招聘 6、程序员面试题库 7、办公、开发软件 8、高清图片、视频素材网站 9、项目开源 10、算法 11、在线工具宝典大全 程序员开发需要具备良好的信息检索能力,为了备忘(收藏夹真是满了),将开发过程中常用的网站进行整理。 1、搜索引擎 1.1、秘迹搜索 一款无敌有良心、无敌安全的搜索引擎,不会收...
996下的程序员,该如何保证自己的身体健康?
作者:陈大鱼头github:KRISACHAN自从开始写代码之后,一天里大部分的时间都贡献了给了电脑跟那张从X总办公室里搬回来的人体工学椅了。鱼头也经历过无数次的 肥胖 ...
史上最详细的IDEA优雅整合Maven+SSM框架(详细思路+附带源码)
网上很多整合SSM博客文章并不能让初探ssm的同学思路完全的清晰,可以试着关掉整合教程,摇两下头骨,哈一大口气,就在万事具备的时候,开整,这个时候你可能思路全无 ~中招了咩~ ,还有一些同学依旧在使用eclipse或者Myeclipse开发,我想对这些朋友说IDEA 的编译速度很快,人生苦短,来不及解释了,直接上手idea吧。这篇文章每一步搭建过程都测试过了,应该不会有什么差错。本文章还有个比较优秀的特点,就是idea的使用,基本上关于idea的操作都算是比较详细的,所以不用太担心不会撸idea!最后,本文
全球最厉害的 14 位程序员!
来源 | ITWorld 整理自网络全球最厉害的 14 位程序员是谁?今天就让我们一起来了解一下吧,排名不分先后。01. Jon Skeet个人名望:程序技术问答网站 S...
我花了一夜用数据结构给女朋友写个H5走迷宫游戏
起因 又到深夜了,我按照以往在csdn和公众号写着数据结构!这占用了我大量的时间!我的超越妹妹严重缺乏陪伴而 怨气满满! 而女朋友时常埋怨,认为数据结构这么抽象难懂的东西没啥作用,常会问道:天天写这玩意,有啥作用。而我答道:能干事情多了,比如写个迷宫小游戏啥的! 当我码完字准备睡觉时:写不好别睡觉! 分析 如果用数据结构与算法造出东西来呢? ...
招人!入职阿里仅1年,我和做AI的程序员薪资翻了2倍!
最近在知乎上,关于AI的这个话题又被顶起来,其中,这条回答让人印象深刻:在这短短的一条信息里,无疑显示出:AI行业缺人,高端岗位80万年薪恐怕也招不来!小编上周在一个AI...
什么是大公司病(太形象了)
点击蓝色“五分钟学算法”关注我哟加个“星标”,天天中午 12:15,一起学算法作者 | 南之鱼来源 | 芝麻观点(chinamkt)所谓大企业病,一般都具有机构臃肿、多重...
让程序员崩溃的瞬间(非程序员勿入)
今天给大家带来点快乐,程序员才能看懂。 来源:https://zhuanlan.zhihu.com/p/47066521 1. 公司实习生找 Bug 2.在调试时,将断点设置在错误的位置 3.当我有一个很棒的调试想法时 4.偶然间看到自己多年前写的代码 5.当我第一次启动我的单元测试时 ...
Spring高级技术梳理
Spring高级技术梳理 序言正文SpringDate部分Spring全家桶之SpringData——预科阶段Spring全家桶之SpringData——Spring 整合Hibernate与Hibernate JpaSpring全家桶之SpringData——Spring Data JPASpring全家桶之SpringData——SpringData RedisSpringBoot部分Sp...
Git 天天用 但是 Git 原理你了解吗?
Git 原理 做技术一定要知其然知其所以然,意思就是:知道它是这样的,更知道它为什么是这样的。我主要通过4块内容来简单介绍 Git 是原理是什么样的。这4块内容如下: Git 存储目录结构介绍 Git 是如何存储的 Git 的对象 Git引用 当然 Git 原理不仅仅包含这些,想要更深入了解请查看官方教程 https://git-scm.com/book/zh/v2/。 本文内容是我在 Git...
Android——微信自动回复实现
首先本文的测试微信版本是7.0.3 ,亲测可以使用。 需要实现-抓取微信自动回复消息的功能点。 一.首先打开DDMS,使用按钮。 在微信中回复一个消息 点击Stop Method Profiling。 二.查看生成的报表,观察到如下两个方法 其中1应该是发送消息的接口方法。2应该是UI层显示的方法。 三.首先分析第一个方法: 1.,可以看到,参数值是String,返...
分享靠写代码赚钱的一些门路
作者 mezod,译者 josephchang10如今,通过自己的代码去赚钱变得越来越简单,不过对很多人来说依然还是很难,因为他们不知道有哪些门路。今天给大家分享一个精彩...
对计算机专业来说学历真的重要吗?
我本科学校是渣渣二本,研究生学校是985,现在毕业五年,校招笔试、面试,社招面试参加了两年了,就我个人的经历来说下这个问题。 这篇文章很长,但绝对是精华,相信我,读完以后,你会知道学历不好的解决方案,记得帮我点赞哦。 先说结论,无论赞不赞同,它本质就是这样:对于技术类工作而言,学历五年以内非常重要,但有办法弥补。五年以后,不重要。 目录: 张雪峰讲述的事实 我看到的事实 为什么会这样 ...
技术人员要拿百万年薪,必须要经历这9个段位
很多人都问,技术人员如何成长,每个阶段又是怎样的,如何才能走出当前的迷茫,实现自我的突破。所以我结合我自己10多年的从业经验,总结了技术人员成长的9个段位,希望对大家的职...
8000字干货:那些很厉害的人是怎么构建知识体系的
本文约8000字,正常阅读需要15~20分钟。读完本文可以获得如下收益: 分辨知识和知识体系的差别 理解如何用八大问发现知识的连接点; 掌握致用类知识体系的构建方法; 能够应用甜蜜区模型找到特定领域来构建知识体系。 1. 知识体系?有必要吗? 小张准备通过跑步锻炼身体,可因为之前听说过小腿变粗、膝盖受伤、猝死等等与跑步有关的意外状况,有点担心自己会掉进各种坑里,就在微信上问朋友圈一直晒跑步...
万字长文!线性代数的本质课程笔记完整合集
点击上方“Datawhale”,选择“星标”公众号第一时间获取价值内容系列目录1.向量究竟是什么https://www.bilibili.com/video/av5987...
Java 网络爬虫,就是这么的简单
这是 Java 网络爬虫系列文章的第一篇,如果你还不知道 Java 网络爬虫系列文章,请参看 学 Java 网络爬虫,需要哪些基础知识。第一篇是关于 Java 网络爬虫入门内容,在该篇中我们以采集虎扑列表新闻的新闻标题和详情页为例,需要提取的内容如下图所示: 我们需要提取图中圈出来的文字及其对应的链接,在提取的过程中,我们会使用两种方式来提取,一种是 Jsoup 的方式,另一种是 httpcli...
nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件
文章目录前言一、nginx简介1. 什么是 nginx 和可以做什么事情2.Nginx 作为 web 服务器3. 正向代理4. 反向代理5. 动静分离6.动静分离二、Nginx 的安装三、 Nginx 的常用命令和配置文件四、 Nginx 配置实例 1 反向代理五、 Nginx 配置实例 2 负载均衡六、 Nginx 配置实例 3 动静分离七、 Nginx 的高可用集群 前言 一、nginx简介...
Java 爬虫遇上数据异步加载,试试这两种办法!
这是 Java 爬虫系列博文的第三篇,在上一篇 Java 爬虫遇到需要登录的网站,该怎么办? 中,我们简单的讲解了爬虫时遇到登录问题的解决办法,在这篇文章中我们一起来聊一聊爬虫时遇到数据异步加载的问题,这也是爬虫中常见的问题。 现在很多都是前后端分离项目,这会使得数据异步加载问题更加突出,所以你在爬虫时遇到这类问题不必惊讶,不必慌张。对于这类问题的解决办法总体来说有以下两种: 1、内置一个浏览器内...
Angular 入门教程系列:39:使用ng-alain进行开发
在前面的文章中介绍过ng-alain,当时在使用的时候还显得不是很方便,最简单的一个demo运行的都不是非常流畅。而目前的版本已经做有较大的改进,再这个基础上进行二次开发,尤其是一些后端的平台或者监控的平台看起来都比较不错。在这篇文章中继续来确认一下使用的感受。
相关热词 c#该名称在封闭局部范围 c#泛型 排序 c# 测试连接mysql c# 多线程 调用界面值 c# gdi unity c#反射构造带参对象 一起自学c# c#工厂方法 c# 对象属性保存xml u3d用c#写拾取物品