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

IO多路复用

IO多路复用---

①select:
      1. 创建文件描述符集合   fd_set
      2. 添加文件描述符到集合中 void FD_SET(int fd, fd_set *set);
      3. 通知内核开始监测        select
      4. 根据返回的结果做对应的操作(对io读、写操作)

 int select(int nfds,

fd_set *readfds,

fd_set *writefds,

fd_set *exceptfds,

struct timeval *timeout);

功能:监测多路IO

参数:

 nfds : 关注的文件描述符中的最大值+1

 readfds:关注的读事件的文件描述符集

writefds:关注的写事件的文件描述符集合exceptfds:其他  异常

timeout : 超时时间,如果不设置:NULL

返回值:

成功:返回到达事件的个数

失败:-1

设置了超时时间:超时时间到达但没有事件,返回0
                     

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);

读操作

#include "head.h"int main(int argc, const char *argv[])
{int maxfd = 0;char buff[1024] = {0};mkfifo("./myfifo", 0664);int fifofd = open("./myfifo", O_RDONLY);if (-1 == fifofd){perror("fail open fifo");return -1;}//创建文件描述符集合fd_set rdfds;fd_set tmpfds;//清空集合FD_ZERO(&rdfds);//添加关注的文件描述符到集合中FD_SET(0, &rdfds);maxfd = 0 > maxfd ? 0 : maxfd;FD_SET(fifofd, &rdfds);maxfd = fifofd > maxfd ? fifofd : maxfd;while (1){tmpfds = rdfds;//开始监测集合中的ioint cnt = select(maxfd+1, &tmpfds, NULL, NULL, NULL);if (cnt < 0){perror("fail select");return -1;}//根据返回的结果区分处理不同的ioif (FD_ISSET(0,&tmpfds)){memset(buff, 0, sizeof(buff));fgets(buff, sizeof(buff), stdin);printf("STDIN : %s\n", buff);}if (FD_ISSET(fifofd, &tmpfds)){memset(buff, 0, sizeof(buff));read(fifofd, buff, sizeof(buff));printf("FIFO : %s\n", buff);}}close(fifofd);return 0;
}

写操作

​
#include "head.h"int main(int argc, const char *argv[])
{	mkfifo("./myfifo", 0664);int fd = open("./myfifo", O_WRONLY);if (-1 == fd){perror("fail open fifo");return -1;}while (1){write(fd, "hello world", 11);sleep(1);}close(fd);return 0;
}​

服务器

#include "head.h"int init_tcp_ser(const char *ip ,unsigned short port)
{	int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sockfd){perror("fail socket");return -1;}struct sockaddr_in ser;ser.sin_family = AF_INET;ser.sin_port = htons(port);ser.sin_addr.s_addr = inet_addr(ip);int ret = bind(sockfd, (struct sockaddr *)&ser, sizeof(ser));if (-1 == ret){perror("fail bind");return -1;}ret = listen(sockfd, 128);if (-1 == ret){perror("fail listen");return -1;}return sockfd;
}int main(int argc, const char *argv[])
{pid_t pid = 0;int connfd = 0;pthread_t tid;int maxfd = 0;char buff[1024] = {0};int sockfd = init_tcp_ser("192.168.175.128", 50000);if (-1 == sockfd){return -1;}fd_set rdfds;fd_set tmpfds;FD_ZERO(&rdfds);FD_SET(sockfd, &rdfds);maxfd = sockfd > maxfd ? sockfd : maxfd;while (1){tmpfds = rdfds;int cnt = select(maxfd+1, &tmpfds, NULL, NULL, NULL);if (cnt < 0){perror("fail select");return -1;}if (FD_ISSET(sockfd, &tmpfds)){int connfd = accept(sockfd, NULL, NULL);if (connfd < 0){perror("fail accept");continue;}FD_SET(connfd, &rdfds);maxfd = connfd > maxfd ? connfd : maxfd;}for (int i = sockfd+1; i < maxfd; i++){if (FD_ISSET(i, &tmpfds)){memset(buff, 0, sizeof(buff));ssize_t size = recv(i, buff, sizeof(buff), 0);if (size < 0){perror("fail recv");FD_CLR(i, &rdfds);close(i);continue;}else if (0 == size){FD_CLR(i, &rdfds);close(i);continue;	}printf("cli---> %s\n", buff);strcat(buff, "------ok!");size = send(i, buff, strlen(buff), 0);if (size < 0){perror("fail recv");FD_CLR(i, &rdfds);close(i);continue;		}}}}return 0;
}

②epoll

 1. 创建文件描述符集合 int epoll_create(int size);

      2. 添加文件描述符到集合中 epoll_ctl()

      3. 通知内核开始监测 epoll_wait()

      4. 根据返回的结果做对应的操作(对io读、写操作)

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

功能:

参数:

          epfd:文件描述符集合句柄

          op: 

                   EPOLL_CTL_ADD: 向集合中添加文件描述符

                   EPOLL_CTL_MOD: 修改集合

                   EPOLL_CTL_DEL :删除文件描述符

          

          fd :操作的文件描述符

         event :文件描述符所对应的事件

 

 

          typedef union epoll_data {

               void *ptr;

               int fd;

               uint32_t u32;

               uint64_t u64;

           } epoll_data_t;

 

           struct epoll_event {

               uint32_t events; /* Epoll events */

               epoll_data_t data; /* User data variable */

           };

 

          event : EPOLLIN : 读操作

                       EPOLLOUT : 写事件

    int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

   功能:监测IO事件

   参数:

             epfd : 文件描述符集合句柄

             events : 保存到达事件的结合的首地址

             maxevents : 监测时事件的个数

            timeout:超时时间

                           -1 :不设置超时时间

返回值:

          成功:返回到达事件的个数

          失败:-1

          设置超时:超时时间到达返回0

读操作

#include "head.h"int epoll_add_fd(int epfds, int fd, uint32_t event)
{struct epoll_event ev;ev.events = event;ev.data.fd = fd;int ret = epoll_ctl(epfds, EPOLL_CTL_ADD, fd, &ev);if (-1 == ret){perror("fail epoll_ctl add");return -1;}return 0;
}int epoll_del_fd(int epfds, int fd)
{int ret = epoll_ctl(epfds, EPOLL_CTL_DEL, fd, NULL);if (-1 == ret){perror("fail epoll_ctl del");return -1;}return 0;
}int main(int argc, const char *argv[])
{int maxfd = 0;char buff[1024] = {0};mkfifo("./myfifo", 0664);int fifofd = open("./myfifo", O_RDONLY);if (-1 == fifofd){perror("fail open fifo");return -1;}struct epoll_event evs[2];int epfds = epoll_create(2);if (-1 == epfds){perror("fail epoll_create");return -1;}epoll_add_fd(epfds, 0, EPOLLIN);epoll_add_fd(epfds, fifofd, EPOLLIN);while (1){int cnt = epoll_wait(epfds, evs, 2, -1);if (cnt < 0){perror("fail epoll_wait");return -1;}for (int i = 0; i < cnt; i++){if (0 == evs[i].data.fd){memset(buff, 0, sizeof(buff));fgets(buff, sizeof(buff), stdin);printf("STDIN: %s\n", buff);}else if (fifofd == evs[i].data.fd){memset(buff, 0, sizeof(buff));ssize_t size = read(evs[i].data.fd, buff, sizeof(buff));if (size <= 0){epoll_del_fd(epfds, evs[i].data.fd);close(evs[i].data.fd);continue;}printf("FIFO: %s\n", buff);}}}return 0;
}

写操作

#include "head.h"int main(int argc, const char *argv[])
{	mkfifo("./myfifo", 0664);int fd = open("./myfifo", O_WRONLY);if (-1 == fd){perror("fail open fifo");return -1;}while (1){write(fd, "hello world", 11);sleep(1);}close(fd);return 0;
}

 

 


http://www.mrgr.cn/news/13616.html

相关文章:

  • CSS动画的使用
  • 遗传算法优化支持向量机代码(输出world报告)
  • 力扣380.O(1)时间的插入删除和获取随机元素
  • 【数据结构】优先级队列 — 堆
  • Spark MLlib模型训练—分类算法 Decision tree classifier
  • Amos百度云下载与安装 附图文安装教程
  • 读软件开发安全之道:概念、设计与实施12不受信任的输入
  • StarRocks 巧用 Storage Volume,强大又便捷
  • el-dialog中使用el-uplode滚动条穿模问题
  • 【工作实践】MVEL 2.x语法指南
  • 搜索引擎通过分析网页标题中的关键词来判断内容的相关性
  • 判别分析分类上接贝叶斯决策,下接最小距离分类
  • hyperf json-rpc
  • 3.服务注册_服务发现
  • Qt第十九章 网络编程
  • vim 简易配置
  • Disassembly窗口信息解读
  • 数据结构(Java实现):栈和队列相关练习题题解
  • Ruff :是一个用Rust编写的极快的 Python linter 和代码格式化程序
  • 推荐一款强大的 macOS 剪贴板增强工具:CleanClip