linux下I/O多路复用技术基础知识

基础知识:I/O多路复用常用技术
    根据服务端或客户端对I/O操作的不同,网络编程人员须选择不同的多路
复用模型,在大多数情况下,单类模型已不能满足复杂业务要求,此时更多的是
采用几类I/O复用的组合形式。
    select、poll、epoll等是linux下常用的I/O多路复用API,以此
衍生出的大规模并发网络编程模型如PPC、TPC等。
    1.PPC/TPC思想是为每一个到来的连接创建进程(PPC)和线程(TPC)由
派生的进程和线程处理业务,此模型当连接数多时进程和线程间的切换开销不可
忽略,适用于最大连接数不多的情况。
    2.select:对于公平的轮询业务操作来说适应性较好,但也存在最大并发数限制,
由于单个进程打开的文件描述符有限(FD_SETSIZE默认为1024/2048),select每次
调用为线性扫描FD集合,效率会线性下降,且存在内核到用户空间的内存拷贝问题。
    3.epoll:
      3.1 epoll无最大并发连接数限制,上限是最大可打开文件数目,该文件数目
和系统内存大小有关;
      3.2 epoll只关心活跃的连接,不产生无效轮询;
      3.3 epoll使用了类似共享内存方式,无内存拷贝操作;
      3.4 epoll通知用户态有I/0事件到来,并通过结构体告诉应用程序已经注册的相关事件的信息,

根据事件信息用户态直接定位到事件,不必遍历整个FD集合。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用C语言编写Web服务器可以使用I/O多路复用技术提高服务器的性能和并发能力。以下是基于Linux下的I/O多路复用的Web服务器实现步骤: 1. 创建socket并绑定IP地址和端口号 2. 将socket设置为非阻塞模式 3. 创建epoll句柄,并将socket加入epoll监听列表中 4. 进入事件循环,等待客户端连接请求 5. 当有客户端连接请求到来时,使用accept函数接受连接,并将新连接加入epoll监听列表中 6. 当有读写事件到来时,使用recv和send函数进行读写操作 7. 关闭连接,从epoll监听列表中删除连接 下面是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <arpa/inet.h> #include <sys/socket.h> #include <sys/epoll.h> #define MAX_EVENTS 1024 #define BUFFER_SIZE 1024 int main(int argc, char *argv[]) { struct sockaddr_in address; int listenfd, connfd, epollfd, nfds, n, i; char buffer[BUFFER_SIZE]; struct epoll_event ev, events[MAX_EVENTS]; if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } memset(&address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_addr.s_addr = htonl(INADDR_ANY); address.sin_port = htons(8080); if (bind(listenfd, (struct sockaddr *)&address, sizeof(address)) == -1) { perror("bind"); exit(1); } if (listen(listenfd, 5) == -1) { perror("listen"); exit(1); } if ((epollfd = epoll_create(1)) == -1) { perror("epoll_create"); exit(1); } ev.events = EPOLLIN; ev.data.fd = listenfd; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listenfd, &ev) == -1) { perror("epoll_ctl"); exit(1); } while (1) { nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1); if (nfds == -1) { perror("epoll_wait"); exit(1); } for (i = 0; i < nfds; i++) { if (events[i].data.fd == listenfd) { if ((connfd = accept(listenfd, (struct sockaddr *)NULL, NULL)) == -1) { perror("accept"); exit(1); } ev.events = EPOLLIN | EPOLLET; ev.data.fd = connfd; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd, &ev) == -1) { perror("epoll_ctl"); exit(1); } } else { if ((n = recv(events[i].data.fd, buffer, BUFFER_SIZE, 0)) <= 0) { close(events[i].data.fd); continue; } buffer[n] = '\0'; printf("Received message: %s\n", buffer); if (send(events[i].data.fd, buffer, n, 0) == -1) { perror("send"); exit(1); } } } } close(listenfd); close(epollfd); return 0; } ``` 此示例代码只是一个简单的Web服务器,可以作为你自己的Web服务器的基础框架。如果需要完善的功能,你需要进一步完善代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值