当前位置: 首页 > wzjs >正文

凡诺企业网站管理系统东莞市微信网站建设品牌

凡诺企业网站管理系统,东莞市微信网站建设品牌,企业网络拓扑图及说明,网站设计的网站I/O 多路复用允许一个进程或线程同时监控多个网络 sockets 的状态。它通过单个系统调用(select)来检查多个 sockets 是否有数据可读、可写或是否有异常。Linux 提供了多种 I/O 复用技术,包括上面提到的 select、以及 poll、epoll。 创建epol…

I/O 多路复用允许一个进程或线程同时监控多个网络 sockets 的状态。它通过单个系统调用(select)来检查多个 sockets 是否有数据可读、可写或是否有异常。Linux 提供了多种 I/O 复用技术,包括上面提到的 select、以及 poll、epoll。

创建epoll epoll_create

int epoll_fd = epoll_create(1);
if (epoll_fd == -1) {perror("epoll_create1 failed");close(server_fd);return 1;
}

epoll_create创建一个 epoll 实例,并返回一个文件描述符,该文件描述符用于后续的 epoll 操作,如 epoll_ctl 和 epoll_wait,epoll_create参数是一个正整数,用于提示内核该 epoll 实例将监控的文件描述符数量。从 Linux 2.6.8 开始,这个参数被忽略,但必须大于零。

监听事件 epoll_ctl

epoll_event event{};
event.events = EPOLLIN;
event.data.fd = server_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event) == -1) {perror("epoll_ctl failed");close(server_fd);close(epoll_fd);return 1;
}

创建epoll对象后,可以用epoll_ctl添加或删除所要监听的socket,并设置相应的监听事件。下面是函数原型

/* Manipulate an epoll instance "epfd". Returns 0 in case of success,-1 in case of error ( the "errno" variable will contain thespecific error code ) The "op" parameter is one of the EPOLL_CTL_*constants defined above. The "fd" parameter is the target of theoperation. The "event" parameter describes which events the calleris interested in and any associated user data.  */
extern int epoll_ctl (int __epfd, int __op, int __fd,struct epoll_event *__event) __THROW;
  • epfd:epoll句柄,由epoll_create创建。
  • op:操作类型,可以是EPOLL_CTL_ADD注册新的fd到epfd中、EPOLL_CTL_MOD修改已经注册的fd的监听事件、EPOLL_CTL_DEL从epfd中删除一个fd。
  • fd:被监听的文件描述符。
  • event:指向epoll_event结构体的指针,用于描述监听事件和事件附加数据。
    下面是epoll_event的具体实现
struct epoll_event{uint32_t events;    //Epoll 事件epoll_data_t data;  //用户数据
}

events用于指定监听的事件

  • EPOLLIN 表示文件描述符可读
  • EPOLLOUT 表示文件描述符可写
  • EPOLLET 表示使用边缘触发(Edge-Triggered)模式,而不是默认的水平触发(Level-Triggered)模式。
  • 水平触发(LT):当一个文件描述符处于就绪状态时,它会持续不断地向程序发送通知,直到该文件描述符不再处于就绪状态。例如,当一个套接字有数据可读时,epoll会一直通知程序进行读取操作,直到所有数据都被读取完毕。这种模式下,程序可以多次读取数据,无需关心是否一次性读取所有数据。
    适用于对性能要求不高或开发难度优先考虑的场景。例如,小型网络应用程序或简单的I/O操作。
  • 边缘触发(ET):只有当一个文件描述符的状态发生变化时,才会触发一次通知。例如,当一个套接字有数据可读时,epoll只会通知一次,之后需要程序一次性读取所有数据。如果程序没有读取完所有数据,epoll不会再次通知,直到该套接字再次有新的数据可读。
    适用于高并发、大数据量传输等对性能要求较高的场景。例如,大型网络服务器、高性能计算等。
    data成员用于存储用户数据,其类型epoll_data_t的定义如下:
typedef union epoll_data
{void *ptr;int fd;uint32_t u32;uint64_t u64;
} epoll_data_t;

epoll_data_t是一个共用体,其4个成员中使用最多的是fd,它指定事件所从属的目标文件描述符。ptr成员可以用来指定与fd相关的用户数据。但由于epoll_data_t是一个共用体,我们不能同时使用其ptr成员和fd成员,因此,如果要将文件描述符和用户数据关联起来,以实现快速的数据访问,只能放弃使用epoll_data_t的fd成员,而在ptr指向的用户数据中包含fd。

epoll_wait

它会等待一组文件描述符上的事件,阻塞等待注册的事件发生,返回事件的数目

// 用于设置最大事件量
epoll_event events[MAX_EVENTS];
// epoll_wait会一直阻塞只有有事件发送
int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
if (num_events == -1) {perror("epoll_wait failed");break;
}

其原型如下:

/* Wait for events on an epoll instance "epfd". Returns the number oftriggered events returned in "events" buffer. Or -1 in case oferror with the "errno" variable set to the specific error code. The"events" parameter is a buffer that will contain triggeredevents. The "maxevents" is the maximum number of events to bereturned ( usually size of "events" ). The "timeout" parameterspecifies the maximum wait time in milliseconds (-1 == infinite).This function is a cancellation point and therefore not marked with__THROW.  */
extern int epoll_wait (int __epfd, struct epoll_event *__events,int __maxevents, int __timeout);
  • epfd :epoll_create()的返回值;
  • events: 用来记录被触发的events(结构参考epoll_ctl),其大小受制于maxevents
  • maxevents: 设定最多监听多少个事件,必须大于0,一般设定为65535
  • timeout:在函数调用中阻塞时间上限,单位是ms
    • timeout = -1:表示调用将一直阻塞,直到有文件描述符进入ready状态或者捕获到信号才返回;
    • timeout = 0:用于非阻塞检测是否有描述符处于ready状态,不管结果怎么样,调用都立即返回;
    • timeout > 0:表示调用将最多持续timeout时间,如果期间有检测对象变为ready状态或者捕获到信号则返回,否则直到超时。
      成功时返回就绪的文件描述符个数,并且将用户详细放入epoll_event数组中
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <iostream>#define BUFFER_SIZE 1024
#define MAX_EVENTS 65535// 设置文件描述符为非阻塞模式
int set_nonblocking(int fd) {int flags = fcntl(fd, F_GETFL, 0);if (flags == -1) return -1;return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}int main(){int server_fd = socket(AF_INET, SOCK_STREAM, 0);if (server_fd == -1) {std::cerr << "socket error" << std::endl;return 1;}// 设置地址重用int opt = 1;if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1){std::cerr << "setsockopt error" << std::endl;return 1;}// 绑定地址和端口sockaddr_in address{};address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(12355);if (bind(server_fd, (sockaddr*)&address, sizeof(address)) < 0) {perror("bind failed");close(server_fd);return 1;}// 开始监听if (listen(server_fd, SOMAXCONN) < 0) {perror("listen failed");close(server_fd);return 1;}std::cout << "Server is listening on port 12355..." << std::endl;// 创建epoll实例int epoll_fd = epoll_create(1);if (epoll_fd == -1) {perror("epoll_create1 failed");close(server_fd);return 1;}// 添加服务器套接字到epollepoll_event event{};event.events = EPOLLIN;event.data.fd = server_fd;if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event) == -1) {perror("epoll_ctl failed");close(server_fd);close(epoll_fd);return 1;}// 用于设置最大事件量epoll_event events[MAX_EVENTS];while (true) {// 事件循环// epoll_wait会一直阻塞只有有事件发送int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);if (num_events == -1) {perror("epoll_wait failed");break;}for (int i = 0; i < num_events; ++i) {// 处理新连接if (events[i].data.fd == server_fd) {sockaddr_in client_addr{};socklen_t client_len = sizeof(client_addr);int client_fd = accept(server_fd, (sockaddr*)&client_addr, &client_len);if (client_fd == -1) {perror("accept failed");continue;}// 设置为非阻塞模式set_nonblocking(client_fd);// 添加客户端到epollepoll_event client_event{};client_event.events = EPOLLIN | EPOLLET; // 边缘触发模式client_event.data.fd = client_fd;if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &client_event) == -1) {perror("epoll_ctl client add failed");close(client_fd);continue;}std::cout << "New connection from: " << inet_ntoa(client_addr.sin_addr) << ":"<< ntohs(client_addr.sin_port) << std::endl;} else {// 处理客户端数据int client_fd = events[i].data.fd;char buffer[BUFFER_SIZE];ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE);if (bytes_read <= 0) {// 连接关闭或错误if (bytes_read == 0 || (bytes_read == -1 && errno != EAGAIN)) {std::cout << "Connection closed" << std::endl;epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);close(client_fd);}continue;}// 简单回显处理buffer[bytes_read] = '\0';std::cout << "Received: " << buffer;write(client_fd, buffer, bytes_read);}}}close(server_fd);close(epoll_fd);return 0;
}

文章转载自:

http://PXxnpSBk.rzbgn.cn
http://eLOgD8NJ.rzbgn.cn
http://5bpAxnB7.rzbgn.cn
http://ganFWavQ.rzbgn.cn
http://mWok3m81.rzbgn.cn
http://TtFY4E7e.rzbgn.cn
http://3ZmceAG3.rzbgn.cn
http://SKcyTXmi.rzbgn.cn
http://1zemV2pS.rzbgn.cn
http://Kp1Jxkzg.rzbgn.cn
http://NCOn3l0a.rzbgn.cn
http://HnUG6ZGQ.rzbgn.cn
http://ES5GnYYi.rzbgn.cn
http://ngMcQArx.rzbgn.cn
http://7JCIhT3t.rzbgn.cn
http://2fnTHuvD.rzbgn.cn
http://zdpPo6wU.rzbgn.cn
http://FUCQ4RCM.rzbgn.cn
http://9BqRyln6.rzbgn.cn
http://FtlbZfVh.rzbgn.cn
http://faeqdund.rzbgn.cn
http://oGUZlgXe.rzbgn.cn
http://HQIFwo6V.rzbgn.cn
http://wvBSBwy8.rzbgn.cn
http://iKdVPkT9.rzbgn.cn
http://Nyj76PVV.rzbgn.cn
http://WBuxQkxL.rzbgn.cn
http://eDGEtwwT.rzbgn.cn
http://gfHvTsqn.rzbgn.cn
http://7CSkgXEk.rzbgn.cn
http://www.dtcms.com/wzjs/739260.html

相关文章:

  • 网站服务器租用平台网站设计不同的原因
  • 上国外网站的dnswordpress怎么添加菜单
  • 怎么拥有网站的所有权什么公司做企业网站
  • 住房和城乡建设部网站办事大厅eclipes 网站开发
  • 东莞网站建设公司招聘信息行业网站建设费用明细
  • 酒店网站建设项目报告书网页动态效果
  • 做淘宝网站需要什么西安app软件开发公司
  • 白银做网站国外网站谷歌seo推广
  • 淘宝优惠券微网站开发北京快速建站模板
  • 响应式网站建设资讯网络营销方案案例
  • thinkphp5做的网站北京网页设计工资
  • 浙江响应式网站建设制作制作宣传片拍摄公司
  • 三大框架网站开发wordpress主题黑糖
  • 电子类网站建设需要多少钱丽水哪里做网站
  • 查询网站dns服务器怎么做网站建设
  • 网站是做流程图中国百强企业
  • 广东网站备案要求江苏省建设工程协会网站
  • 怎么让网站绑定域名电子商务微网站制作
  • 济南在线制作网站html个人网页源码
  • 仪器仪表网站制作湖北建设人力资源网站
  • 电商网站开发工作计划成都网站建设scjsc888
  • 深圳市住建局网站官网wordpress命令执行时间
  • 网站手机版方案一级建造师考试科目
  • 做海鲜团购网站刚开始做汽配网站要进货
  • 手机网站建设的费用深圳装修公司网站
  • 做网站 徐州网站建设维护费一年多少钱
  • 网站的分类有哪些类型微信对接网站
  • 谷歌云做网站服务器网站后台无法编辑文字
  • 合肥做公司网站公司陕西网站建设品牌公司推荐
  • 怎么用手机做网站平台做云词图的网站