epoll分布式通讯
参考http://www.xmailserver.org/linux-patches/nio-improve.html epoll通讯
参考https://blog.csdn.net/yangquanhui1991/article/details/47446245?locationNum=4&fps=1任务调度算法
注意: select/poll/epoll的作用是IO复用, 要实现并发, 还是需要交个其他线程/进程去处理。 业界很多成熟的服务组件, 就是这么玩的, 如nginx.
创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大。这个参数不同于select()中的第一个参数,给出最大监听的fd+1的值。需要注意的是,当创建好epoll句柄后,它就是会占用一个fd值,在linux下如果查看/proc/进程id/fd/,是能够看到这个fd的,所以在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽。
eg:
#include <iostream>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
using namespace std;
#define MAXLINE 5
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 5000
#define INFTIM 1000
void setnonblocking(int sock)//将套接字设置为非阻塞
{
int opts;
opts=fcntl(sock,F_GETFL);
if(opts<0)
{
perror("fcntl(sock,GETFL)");
exit(1);
}
opts = opts|O_NONBLOCK;
if(fcntl(sock,F_SETFL,opts)<0)
{
perror("fcntl(sock,SETFL,opts)");
exit(1);
}
}
int main(int argc, char* argv[])
{
int i, maxi, listenfd, connfd, sockfd,epfd,nfds, portnumber;
ssize_t n;
char line[MAXLINE];
socklen_t clilen;
if ( 2 == argc )
{
if( (portnumber = atoi(argv[1])) < 0 )
{
fprintf(stderr,"Usage:%s portnumber/a/n",argv[0]);
return 1;
}
}
else
{
fprintf(stderr,"Usage:%s portnumber/a/n",argv[0]);
return 1;
}
struct epoll_event ev,events[20]; //声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
epfd=epoll_create(256); //生成用于处理accept的epoll专用的文件描述符
struct sockaddr_in clientaddr;
struct sockaddr_in serveraddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
setnonblocking(listenfd); //把socket设置为非阻塞方式
ev.data.fd=listenfd; //设置与要处理的事件相关的文件描述符
ev.events=EPOLLIN|EPOLLET; //设置要处理的事件类型
epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev); //注册epoll事件
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
char *local_addr="127.0.0.1";
inet_aton(local_addr,&(serveraddr.sin_addr));
serveraddr.sin_port=htons(portnumber);
bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));
listen(listenfd, LISTENQ);
maxi = 0;
for ( ; ; ) {
nfds=epoll_wait(epfd,events,20,500); //等待epoll事件的发生
for(i=0;i<nfds;++i) //处理所发生的所有事件
{
if(events[i].data.fd==listenfd)//如果新监测到一个SOCKET用户连接到了绑定的SOCKET端口,建立新的连接。
{
connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen);
if(connfd<0){
perror("connfd<0");
exit(1);
}
char *str = inet_ntoa(clientaddr.sin_addr);
cout << "accapt a connection from " << str << endl;
ev.data.fd=connfd; //设置用于读操作的文件描述符
ev.events=EPOLLIN|EPOLLET; //设置用于注测的读操作事件
epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev); //注册ev
}
else if(events[i].events&EPOLLIN)//如果是已经连接的用户,并且收到数据,那么进行读入。
{
cout << "EPOLLIN" << endl;
if ( (sockfd = events[i].data.fd) < 0)
continue;
if ( (n = read(sockfd, line, MAXLINE)) < 0) {
if (errno == ECONNRESET) {
close(sockfd);
events[i].data.fd = -1;
} else
std::cout<<"readline error"<<std::endl;
} else if (n == 0) {
close(sockfd);
events[i].data.fd = -1;
}
line[n] = '/0';
cout << "read " << line << endl;
ev.data.fd=sockfd; //设置用于写操作的文件描述符
ev.events=EPOLLOUT|EPOLLET; //设置用于注测的写操作事件
epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); //修改sockfd上要处理的事件为EPOLLOUT
}
else if(events[i].events&EPOLLOUT) // 如果有数据发送
{
sockfd = events[i].data.fd;
write(sockfd, line, n);
ev.data.fd=sockfd; //设置用于读操作的文件描述符
ev.events=EPOLLIN|EPOLLET; //设置用于注测的读操作事件
epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); //修改sockfd上要处理的事件为EPOLIN
}
}
}
return 0;
}
epoll分布式通讯的更多相关文章
- 1.6分布式通讯协议-WebService
RPC 包含的要素(webservice) 协议层:tcp/ip 应用层: http协议 SOAP: http+xml 分布式通信框架-webservice分析 什么是webservice webse ...
- 1.5分布式通讯框架-RMI
分布式通信框架-RMI讲解 什么是RPC Remote procedure call protocal RPC协议其实是一个规范.常用PRC框架:Dubbo.Thrif.RMI.Webservice. ...
- 分布式通讯架构RPC简单实现
什么是RPC: RPC(Remote Procedure Call,远程过程调用),一般用来实现部署在不同机器上的系统之间的方法调用,使得程序能够像访问本地系统资源一样,通过网络传输去访问远端系统资源 ...
- 1.4分布式-通讯协议TCP/IP
服务器和浏览器的通讯依靠http协议,今天就来分析一下http协议的具体内容以及https的加密过程.除了这些协议,为了增加服务器和浏览器交互的可拓展性,也出现了rest风格的请求方式,方便调用接口. ...
- spark下测试akka的分布式通讯功能
采用的spark版本为1.1.0 scala版本为2.10.4 编写scala类文件myactors.scala: package bluejoe import akka.actor._ import ...
- 手撕面试官系列(八):分布式通讯ActiveMQ+RabbitMQ+Kafka面试专题
ActiveMQ专题 (面试题+答案领取方式见主页) 什么是 ActiveMQ? ActiveMQ 服务器宕机怎么办? 丢消息怎么办? 持久化消息非常慢. 消息的不均匀消费. 死信队列. Active ...
- 分布式服务通讯框架XXL-RPC
<分布式服务通讯框架XXL-RPC> 一.简介 1.1 概述 XXL-RPC 是一个分布式服务通讯框架,提供稳定高性能的RPC远程服务调用功能.现已开放源代码,开箱即用. 1.2 特 ...
- Java[2] 分布式服务架构之java远程调用技术浅析(转http://www.uml.org.cn/zjjs/201208011.asp)
转自:http://www.uml.org.cn/zjjs/201208011.asp 在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术,例如: ...
- 分布式服务框架XXL-RPC
<分布式服务框架XXL-RPC> 一.简介 1.1 概述 XXL-RPC 是一个分布式服务框架,提供稳定高性能的RPC远程服务调用功能.拥有"高性能.分布式.注册中心. ...
- 面试阿里被分布式“搞懵”,Redis、MongoDB、memcached没答上来
都说大厂面试难,一点也没有错,一线大厂的面试究竟怎么样还得自己亲身经历了才知道.小白面试阿里,就被面试官吊打,一问分布式就被“搞懵”了,Redis.MongoDB.Memcached都没答好,很多没有 ...
随机推荐
- 上下文管理器 context managet
定义:实现了上下文管理协议的对象,主要用于保存和恢复各种全局状态,关闭文件等,它本身就是一种装饰器. with语句 with语句就是为支持上下文管理器而存在的
- Day2:基本的Dos命令
打开CMD的方式 开始+系统+命令提示符(右键以管理员身份运行可拿到最高权限) Win键+R 输入 cmd打开控制台(推荐使用) 桌面上按住shift+鼠标右键,打开powershell窗口 文件搜索 ...
- Python学习之实例1
一.求n个数字的平均值 n=3 #定义常量n=3 sum=0 #定义求和变量sum count=0 #定义变量count,记录输入数字的次数 print("请输入3个数字:") # ...
- 嵌入式-C语言基础:数组得初始化
#include<stdio.h> int main() { int a[10]; int size=sizeof(a)/sizeof(a[0]);//计算数组得大小 for(int i= ...
- 2022-11-11 Acwing每日一题
本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的.同时也希望 ...
- xmind下载安装破解版激活教程思维导图软件获取
1.xmind下载解压压缩包就可以看到里面的文件,然后双击安装文件就可以开始安装了 2.安装Xmind程序双击之后会出现下面的流程,照着截图操作,不要乱点哈 切记切记!!这一步直接点击next,不要修 ...
- hwlog--logger.go
// Copyright(C) 2021. Huawei Technologies Co.,Ltd. All rights reserved.// Package hwlog provides the ...
- Java-(array)数组的基本概念 及 Java内存划分
(array)数组的基本概念 数组的概念:是一种容器,可同时存放多个数据值 数组的特点: 1.数组是一种引用数据类型 2.数组当中的多个数据,类型必须统一 3.数组的长度在程序运行期间不可改变 数组的 ...
- Python中 or、and 的优先级
上式可以看出 先看 and 输出才为 ture 因此 优先级 and>or
- phpexcel 上传
<?php require_once(ROOTPATH . "inc/PHPExcel/PHPExcel.class.php");//PHPExcel//获取数据 $objP ...