统一事件源epoll代码示例
可以将信号注册进pipe管道的写端,通过对读端的监听,来实现统一事件源。
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h> #include <assert.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pthread.h> #define MAX_EVENT_NUMBER 1024
static int pipefd[]; 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;
epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event);
setnonblocking(fd);
} void sig_handler(int sig) {
int save_errno = errno;
int msg = sig;
send(pipefd[], (char*)&msg, , );
errno = save_errno;
} void addsig(int sig) {
struct sigaction sa;
memset(&sa, '\0', sizeof(sa));
sa.sa_handler = sig_handler;
sa.sa_flags != SA_RESTART;
sigfillset(&sa.sa_mask);
assert(sigaction(sig, &sa, NULL) != -);
} int main(int argc, char *argv[]) {
if (argc <= ) {
printf("usage: %s ip port\n", basename(argv[]));
return ;
}
const char *ip = argv[];
int port = atoi(argv[]); int ret = ;
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); int listenfd = socket(PF_INET, SOCK_STREAM, );
assert(listenfd >= ); ret = bind(listenfd, (sockaddr*)&address, sizeof(address));
if (ret == -) {
printf("errno is %d\n", errno);
return ;
}
ret = listen(listenfd, );
assert(ret != -); epoll_event events[MAX_EVENT_NUMBER];
int epollfd = epoll_create();
assert(epollfd != -);
addfd(epollfd, listenfd); ret = socketpair(PF_UNIX, SOCK_STREAM, , pipefd);
assert(ret != -);
setnonblocking(pipefd[]);
addfd(epollfd, pipefd[]); addsig(SIGHUP);
addsig(SIGCHLD);
addsig(SIGTERM);
addsig(SIGINT);
bool stop_server = false; while (!stop_server) {
int number = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -);
if ((number < ) && (errno != EINTR)) {
printf("epoll failure\n");
break;
} for (int i=; i<number; i++) {
int sockfd = events[i].data.fd;
if (sockfd == listenfd) {
printf("New connection is coming.\n");
sockaddr_in client_address;
socklen_t client_addrlen = sizeof(client_address);
int connfd = accept(listenfd, (sockaddr*)&client_address,
&client_addrlen);
printf("New connection established.\n");
addfd(epollfd, connfd);
}
else if ((sockfd == pipefd[]) && (events[i].events & EPOLLIN)) {
int sig;
char signals[];
ret = recv(pipefd[], signals, sizeof(signals), );
if (ret == -) {
continue;
}
else if (ret == ) {
continue;
}
else {
for (int i=; i<ret; ++i) {
switch(signals[i]) {
case SIGCHLD:
{
printf("SIGCHLD CONTINUE\n");
continue;
}
case SIGHUP:
{
printf("SIGHUP CONTINUE\n");
continue;
}
case SIGTERM:
{
printf("SIGTERM END PROGRAM\n");
stop_server = true;
break;
}
case SIGINT:
{
printf("SIGINT END PROGRAM\n");
stop_server = true;
break;
}
}
}
}
}
else {
// handle connected fd, ignore
}
}
} printf("close fds\n");
close(listenfd);
close(pipefd[]);
close(pipefd[]);
return ; }
Makefile的文件内容:
uniserver : uniserver.cpp
g++ -o uniserver uniserver.cpp -lpthread
编译出服务器程序之后,运行服务器:
$ ./uniserver 127.0.0.1
New connection is coming.
New connection established.
SIGTERM END PROGRAM
close fds
$ ./uniserver 127.0.0.1
^CSIGINT END PROGRAM
close fds
运行客户端:
$ telnet 127.0.0.1
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
a
^C^]
telnet> quit
Connection closed.
$ ps ux | grep uniserver
work 0.0 0.0 pts/ S+ : : ./uniserver 127.0.0.1
work 0.0 0.0 pts/ S+ : : grep uniserver
$ kill
可以看出,客户端的连接请求得到服务器端的响应;发出的内容"a"在服务器端没有处理和展现。
使用向服务器发信号,得到处理;服务器端直接Ctrl+C也得到了处理。
同时可以看出,信号是int类型,但是传输的时候,采用的是char*,并且只传输了一个字节就可以了;在接收端进行switch的时候,也只针对char数据的一个元素进行比对就可以了。
统一事件源epoll代码示例的更多相关文章
- epoll代码示例
#include <errno.h> #include <string.h> #include <stdlib.h> #include <sys/types. ...
- 【NumberValidators】工商营业执照号码和统一社会信用代码验证
从本质上讲,工商营业执照号码和统一社会信用代码是两套完全不一样的编码规则,识别结果也仅有行政区划部分为两者共有,但因为这两种编码同时存在的原因,所以如果需要在系统中唯一标志一家企业时,还是可以通过工商 ...
- Ice简介+Qt代码示例
1.ICE是什么? ICE是ZEROC的开源通信协议产品,它的全称是:The Internet Communications Engine,翻译为中文是互联网通信引擎,是一个面向对象的中间件,它封装并 ...
- MapReduce框架结构及代码示例
一个完整的 mapreduce 程序在分布式运行时有三类实例进程: 1.MRAppMaster:负责整个程序的过程调度及状态协调 2.MapTask:负责 map 阶段的整个数据处理流程 3.Redu ...
- 高级渲染技巧和代码示例 GPU Pro 7
下载代码示例 移动设备正呈现着像素越来越高,屏幕尺寸越来越小的发展趋势. 由于像素着色的能耗非常大,因此 DPI 的增加以及移动设备固有的功耗受限环境为降低像素着色成本带来了巨大的压力. MSAA 有 ...
- Java8-Function使用及Groovy闭包的代码示例
导航 定位 概述 代码示例 Java-Function Groovy闭包 定位 本文适用于想要了解Java8 Function接口编程及闭包表达式的筒鞋. 概述 在实际开发中,常常遇到使用模板模式的场 ...
- [IOS 开发] 懒加载 (延迟加载) 的基本方式,好处,代码示例
懒加载的好处: 1> 不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强 2> 每个属性的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强,松耦合 ...
- SELECT控件操作的JS代码示例
SELECT控件操作的JS代码示例 1 检测是否有选中 if(objSelect.selectedIndex > -1) { //说明选中 } else { //说明没有选中 } 2.动态创建s ...
- 转:HIBERNATE一些_方法_@注解_代码示例---写的非常好
HIBERNATE一些_方法_@注解_代码示例操作数据库7步骤 : 1 创建一个SessionFactory对象 2 创建Session对象 3 开启事务Transaction : hibernate ...
随机推荐
- 每日一九度之 题目1033:继续xxx定律
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5502 解决:1351 题目描述: 当n为3时,我们在验证xxx定律的过程中会得到一个序列,3,5,8,4,2,1,将3称为关键数, ...
- CSS select样式列表-------美化列表
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- sql查询某条记录
select * from (SELECT t.*,ROWNUM AS RN FROM AWARDISSUE_FOOTBALL t ORDER BY ID DESC) WHERE RN=2
- oneThink安装出错解决
在Wampserver3.0.0(apache2.4.17+php5.6.15+mysql5.7.9)版本中oneThink安装用1.1github版,不要用1.1开发版,不然安装的时候数据库导入时b ...
- reactjs入门到实战(八)----表单组件的使用
表单组件支持几个受用户交互影响的属性: value,用于 <input>.<textarea> 组件. checked,用于类型为 checkbox 或者 radio 的 &l ...
- JavaScript的学习
学习了一段时间了,oop 的JavaScript .但是理解了还不是很深入,所以,决定.通过写博客的方式来,加深JavaScript的程度.2016的目标: 第一阶段:oop的JavaScript 第 ...
- java提高篇---Vector
对于List接口这里还介绍一个它的实现类Vector,Vector 类可以实现可增长的对象数组. 一.Vector简介 Vector可以实现可增长的对象数组.与数组一样,它包含可以使用整数索引进行访问 ...
- EasyUI DataGrid 添加排序
这个事例演示了如何在点击列头的时候排序DataGrid中全部的列可以通过点击列头被排序.你可以定义可以被排序的列.默认的,列不能被排序除非你设置sortable属性为TRUE,下面是例子:标记 < ...
- javascript实现二分查找
今天做了道笔试题,要求是实现二分查找,当然不难,想了一下,因为没有要求语言就用javascript实现了.当然,期间还是出来了一点问题. ok,上代码 /* * 稳定二分查找 * 作者:吴伟欣 * * ...
- MD5加密算法
package com.bao.tools.encryption; import java.security.MessageDigest;import java.security.NoSuchAlgo ...