IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> IO复用,select, -> 正文阅读

[系统运维]IO复用,select,

一,IO复用的方法

IO复用的方法:select poll epoll

IO复用的功能

这里的描述符就是套接字

在这里插入图片描述
以前TCP服务器端和客户端
一个服务器端要连接10个客户端就需要创建10个线程
学校发书,所有人在图书馆排队领书没到你你就在等相当于阻塞,另一种到你了我给你打电话你再来领就不会出现阻塞(例子)
在程序中来讲就是我们将所有要关注的描述符全部注册到select上,select帮我们检测哪个描述符上有数据产生(有可能是一个或2,3个上同时有数据)

举个例子来使用select

检测键盘(键盘也是描述符),如果5秒内键盘上有数据的输入,我们就把数据读一下并打印出来,如果5秒内没有数据我们就打印个time out
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

select在Linux上和Windows都有
在这里插入图片描述
在这里插入图片描述

二,一个描述符的select代码

在这里插入图片描述

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<string.h>
  5 #include<sys/select.h>
  6 
  7 #define STDIN 0//0就是从键盘输入
  8 int main()
  9 {
 10  int fd=STDIN;
 11  fd_set fdset;
 12  while(1)
 13  {
 14   FD_ZERO(&fdset);
 15   FD_SET(fd,&fdset);
 16   struct timeval tv={5,0};如果没有输入数据或者还没有到5秒就会在这里阻塞住
 17   int n=select(fd+1,&fdset,NULL,NULL,&tv);// 因为描述符是从0开始的,但fd_    set所置1的的标号是从1开始的(fd+1描述符的最大值+1这里只有一个)
 18   if(n<0)
 19   {
 20    printf("select err\n");
 21   }
 22   else if(n==0)
 23   {
 24    printf("time out\n");
 25   }
 26   else
 27   {
 28    if(FD_ISSET(fd,&fdset))
 29    {
 30     char buff[128]={0};
 31     read(fd,buff,128);
 32     printf("read:%s\n",buff);
 33    }
 34   }
 35  }
 36 }

三,多描述符的代码

将select用到tcp的服务器端
fd是文件描述符
阻塞
如果描述符是sockfd则调用accept()接受连接
在这里插入图片描述
memset(&saddr,0,sizeof(saddr));

封装的fds_init(); fds_add(); fds_del();都是用来对数组进行操作的

1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 #include<string.h>
  5 #include<sys/select.h>
  6 #include<sys/socket.h>
  7 #include<arpa/inet.h>
  8 #include<netinet/in.h>
  9 #include<assert.h>
 10 
 11 #define MAX 10
 12 
 13 
 14 void fds_init(int fds[])//先全部置-1
 15 {
 16  int i=0;
 17  for(;i<MAX;i++)
 18  {
 19   fds[i]=-1;
 20  }
 21 }
 22 
 23 void fds_add(int fd,int fds[])//找空闲的位置将描述符存入数组
 24 {
 25  if(fd<0)
 26  {
 27  return;
 28  }
29  for(int i=0;i<MAX;i++)
 30  {
 31   if(fds[i]==-1)
 32   {
 33    fds[i]=fd;
 34    break;
 35   }
 36  }
 37 }
 38 
 39 void fds_del(int fd,int fds[])//移除描述符
 40 {
 41     for(int i=0;i<MAX;i++)
 42     {
 43      if(fds[i]==fd)
 44      {
 45       fds[i]=-1;
 46       break;
 47      }
 48     }
 49 }
 50 int socket_init();
 51 int main()
 52 {
 53  int sockfd=socket_init();
54  assert(sockfd!=-1);
 55 
 56  int fds[MAX];
 57  fds_init(fds);
 58  fds_add(sockfd,fds);
 59  fd_set fdset;
 60  while(1)
 61  {
 62   FD_ZERO(&fdset);
 63   int maxfd=-1;
 64   for(int i=0;i<MAX;i++)//把有效描述符添加到fdset,并且找到最大描述符
 65   {
 66    if(fds[i]=-1)
 67    {
 68     continue;
 69    }
 70 
 71    FD_SET(fds[i],&fdset);
 72    if(maxfd<fds[i])
 73    {
 74     maxfd=fds[i];
 75    }
 76   }
 77 
 78 struct timeval tv={5,0};
 79 int n=select(maxfd+1,&fdset,NULL,NULL,&tv);
 80 if(n<0)
 81 {
82  printf("select err\n");
 83 }
 84 else if(n==0)
 85   {
 86    printf("time out\n");
 87   }
 88 else
 89   {
 90    for(int i=0;i<MAX;i++)
 91    {
 92      if(fds[i]==-1)
 93      {
 94       continue;
 95      }
 96 
 97      if(FD_ISSET(fds[i],&fdset))//判断是否有读事件
 98       {
 99        if(fds[i]==sockfd)//如果为监听套接字则添加描述符
100         {
101          struct sockaddr_in caddr;
102          int len=sizeof(caddr);
103          int c=accept(sockfd,(struct sockaddr*)&caddr,&len);
104          if(c<0)
105          {
106           continue;
107          }
108          printf("accept c=%d\n",c);
109          fds_add(c,fds);
110         }
111        else//如果为连接套接字则接受数据
112          {
113           char buff[128]={0};
114           int num=recv(fds[i],buff,127,0);
115           if(num<=0)
116           {
117            printf("client close\n");
118            close(fds[i]);
119            fds_del(fds[i],fds);
120           }
121           else
122                {
123                 printf("recv(%d)=%s\n",fds[i],buff);
124                 send(fds[i],"ok",2,0);
125                }
126          }
127       }
128    }
129   }
130  }
131 }
132 
133 int socket_init()
134 {
135  int sockfd=socket(AF_INET,SOCK_STREAM,0);
136  if(sockfd==-1)
137  {
138   return -1;
139  }
140  struct sockaddr_in saddr;
141  memset(&saddr,0,sizeof(saddr));
142  saddr.sin_family=AF_INET;
143  saddr.sin_port=htons(6000);
144  saddr.sin_addr.s_addr=inet_addr("127.0.0.1");
145  int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
146  if(res==-1)
147  {
148  return -1;
149  }
150  res=listen(sockfd,5);
151  if(res==-1)
152  {
153   return -1;
154  }
155 
156  return sockfd;
157 }

客户端是TCP有循环代码

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-04-06 16:28:46  更:2022-04-06 16:31:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 22:29:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码