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

武汉做网站佳针对大学生推广引流

武汉做网站佳,针对大学生推广引流,域名解析网站登录,如何学习做网站深入剖析 I/O 复用之 select 机制 在网络编程中,I/O 复用是一项关键技术,它允许程序同时监控多个文件描述符的状态变化,从而高效地处理多个 I/O 操作。select 作为 I/O 复用的经典实现方式,在众多网络应用中扮演着重要角色。本文…

深入剖析 I/O 复用之 select 机制

在网络编程中,I/O 复用是一项关键技术,它允许程序同时监控多个文件描述符的状态变化,从而高效地处理多个 I/O 操作。select 作为 I/O 复用的经典实现方式,在众多网络应用中扮演着重要角色。本文将深入探讨 select 的原理、使用方法、相关数据结构以及实际应用示例。

一、I/O 复用概述

I/O 复用使得程序能够同时监听多个文件描述符,适用于多种场景:

  • 客户端程序需要同时处理多个套接字。
  • 客户端要兼顾用户输入和网络连接处理。
  • TCP 服务器需同时管理监听套接字和已连接套接字。
  • 服务器要同时处理 TCP 请求和 UDP 请求。
  • 服务器需要监听多个端口。

二、select 原理

select 系统调用通过维护三个文件描述符集合(读集合、写集合和异常集合)来监视不同类型的事件。它会阻塞当前进程,直到有一个或多个文件描述符就绪(有数据可读、可写或发生异常),或者达到指定的超时时间。

三、select 使用方法

函数原型

#include <sys/select.h>  
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);  
  • nfds:需要监视的最大文件描述符编号加 1。
  • readfds:读文件描述符集合,用于监视文件描述符是否有数据可读。
  • writefds:写文件描述符集合,用于监视文件描述符是否可写。
  • exceptfds:异常文件描述符集合,用于监视文件描述符是否发生异常。
  • timeout:超时时间,指定 select 函数的最大阻塞时间。如果为 NULL,则会一直阻塞直到有文件描述符就绪。

fd_set 数据结构

fd_set 用于存储文件描述符集合,本质上是一个位图(bitmask)。每个文件描述符对应位图中的一位,若该位置为 1,则表示该文件描述符在集合内;若为 0,则表示不在集合内。

在这里插入图片描述

操作 fd_set 的宏函数

  • FD_ZERO(fd_set *set):将 fd_set 集合初始化为空,即把集合中所有位都置为 0。
  • FD_SET(int fd, fd_set *set):将指定的文件描述符 fd 添加到 fd_set 集合中,把对应位设置为 1。
  • FD_CLR(int fd, fd_set *set):从 fd_set 集合中移除指定的文件描述符 fd,将对应位设置为 0。
  • FD_ISSET(int fd, fd_set *set):检查指定的文件描述符 fd 是否在 fd_set 集合中。若在集合中则返回非零值,否则返回 0。

timeout 结构体

struct timeval {  long tv_sec; // 秒数  long tv_usec; // 微秒数  
};  

用于指定 select 函数的超时时间。

四、使用 select 实现 TCP 服务器示例代码解析

代码功能

此代码创建了一个 TCP 服务器,借助 select 函数实现 I/O 复用,能够同时处理多个客户端的连接与数据收发。服务器监听本地地址 127.0.0.16000 端口,当有新的客户端连接时会接受连接,接收客户端发送的数据,并向客户端回复 "ok"

代码逐段解析

头文件与常量定义
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
#include <sys/select.h>  
#include <sys/socket.h>  
#include <arpa/inet.h>  
#include <netinet/in.h>  #define MAXARR 10  

引入所需头文件,并定义常量 MAXARR 表示存储文件描述符数组的最大长度。

函数声明与实现
  • socket_init 函数
    int socket_init() {  int sockfd = socket(AF_INET, SOCK_STREAM, 0);  if (sockfd == -1) {  perror("socket err");  return -1;  }  struct sockaddr_in saddr;  memset(&saddr, 0, sizeof(saddr));  saddr.sin_family = AF_INET;  saddr.sin_port = htons(6000);  saddr.sin_addr.s_addr = inet_addr("127.0.0.1");  int res = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));  if (res == -1) {  perror("bind err");  return -1;  }  if ((res = listen(sockfd, 5) < 0)) {  perror("listen err");  return -1;  }  return sockfd;  
    }  
    
    该函数用于初始化服务器套接字,包括创建套接字、绑定地址和端口、开始监听连接。若出现错误则返回 -1
  • arr_init 函数
    void arr_init(int arr[]) {  for (int i = 0; i < MAXARR; i++) {  arr[i] = -1;  }  
    }  
    
    把存储文件描述符的数组初始化为 -1,表示数组中没有有效的文件描述符。
  • arr_add 函数
    void arr_add(int arr[], int fd) {  for (int i = 0; i < MAXARR; i++) {  if (arr[i] == -1) {  arr[i] = fd;  break;  }  }  
    }  
    
    把新的文件描述符添加到数组中,找到第一个值为 -1 的位置,将新的文件描述符存入该位置。
  • arr_del 函数
    void arr_del(int arr[], int fd) {  for (int i = 0; i < MAXARR; i++) {  if (arr[i] == fd) {  arr[i] = -1;  break;  }  }  
    }  
    
    从数组中删除指定的文件描述符,找到该文件描述符所在的位置,将其值置为 -1
  • accept_cli 函数
    void accept_cli(int sockfd, int arr[]) {  int c = accept(sockfd, NULL, NULL);  if (c == -1) {  perror("accept err");  return;  }  printf("cli(%d) accept\n", c);  arr_add(arr, c);  
    }  
    
    接受新的客户端连接,若接受成功则将客户端的套接字文件描述符添加到数组中。
  • recv_cli 函数
    void recv_cli(int fd, int arr[]) {  char buff[128] = {0};  int n = recv(fd, buff, 127, 0);  if (n < 0) {  perror("recv err");  printf("cli(%d) close\n", fd);  close(fd);  arr_del(arr, fd);  return;  }  if (n == 0) {  printf("cli(%d) close\n", fd);  close(fd);  arr_del(arr, fd);  return;  }  printf("buff(c=%d):%s\n", fd, buff);  send(fd, "ok", 2, 0);  
    }  
    
    接收客户端发送的数据,若接收出错或者客户端关闭连接,则关闭对应的套接字并从数组中删除该文件描述符;若接收到数据,则打印数据并向客户端回复 "ok"
main 函数
int main() {  int sockfd = socket_init();  if (sockfd == -1) {  exit(1);  }  int arr[MAXARR];  arr_init(arr);  arr_add(arr, sockfd);  fd_set fdset;  while (1) {  FD_ZERO(&fdset);  int maxfd = -1;  for (int i = 0; i < MAXARR; i++) {  if (arr[i] == -1) {  continue;  }  FD_SET(arr[i], &fdset);  if (arr[i] > maxfd) {  maxfd = arr[i];  }  }  struct timeval tv = {5, 0};  int n = select(maxfd + 1, &fdset, NULL, NULL, &tv);  if (n == -1) {  perror("select err");  continue;  } else if (n == 0) {  printf("TIME OUT\n");  continue;  } else {  for (int i = 0; i < MAXARR; i++) {  if (arr[i] == -1) {  continue;  } else {  if (FD_ISSET(arr[i], &fdset)) {  if (arr[i] == sockfd) {  accept_cli(arr[i], arr);  } else {  recv_cli(arr[i], arr);  }  }  }  }  }  }  
}  
  • 初始化服务器套接字,若失败则退出程序。
  • 初始化存储文件描述符的数组,并将服务器套接字文件描述符添加到数组中。
  • 进入无限循环:
    • 每次循环开始时,清空 fd_set 集合。
    • 遍历数组,将有效的文件描述符添加到 fd_set 集合中,并找出最大的文件描述符。
    • 设置 select 函数的超时时间为 5 秒。
    • 调用 select 函数进行监听,根据返回值判断情况:若返回 -1 表示出错,打印错误信息并继续循环;若返回 0 表示超时,打印超时信息并继续循环;若返回大于 0 的值,表示有文件描述符就绪。
    • 再次遍历数组,检查哪些文件描述符就绪。若为服务器套接字,则调用 accept_cli 函数接受新的连接;若为客户端套接字,则调用 recv_cli 函数接收数据。

五、select 的优缺点

优点

  • 跨平台支持select 是一种标准的系统调用,几乎所有的 Unix/Linux 系统和 Windows 系统都支持,具有良好的跨平台性。
  • 简单易用select 的接口相对简单,使用起来比较方便,对于小规模的应用场景非常适用。

缺点

  • 文件描述符数量限制select 有最大文件描述符数量的限制,一般为 1024。如果需要处理大量的文件描述符,可能会受到限制。
  • 性能问题select 需要遍历所有的文件描述符来检查其状态,时间复杂度为 O(n),当文件描述符数量较多时,性能会受到影响。
  • 内核和用户空间数据拷贝:每次调用 select 时,都需要将文件描述符集合从用户空间拷贝到内核空间,在文件描述符数量较多时,会带来一定的开销。

六、适用场景

由于 select 存在一些局限性,它适用于文件描述符数量较少、对性能要求不是特别高的场景,例如一些简单的网络服务器、嵌入式系统等。在实际应用中,若需要处理大量文件描述符或对性能有更高要求,可以考虑使用 pollepoll 等更高级的 I/O 复用机制。

通过深入理解 select 的原理、使用方法和优缺点,我们能够在网络编程中更好地运用这一技术,构建高效稳定的网络应用。

http://www.dtcms.com/wzjs/56104.html

相关文章:

  • 设计素材网站无版权百度seo软件曝光行者seo
  • 怎么做锅炉网站网上教育培训机构哪家好
  • 平台式网站网络营销与策划试题及答案
  • 网站设计技术公司搜索引擎营销的成功案例
  • 网站建设的认识网站怎么注册
  • 企业网站优化暴肃湖南岚鸿很好长春seo优化企业网络跃升
  • 企业官网建设哪家好seo资料网
  • 做外汇应该看哪一家网站竞价账户托管哪家好
  • 网站怎么做移动图片大全专业关键词排名软件
  • 网站建设的项目总结百度推广怎么做效果好
  • 赣州网站建设-赣州做网站营销网站建站公司
  • 怎样做触屏版手机网站网络运营师资格证
  • 伊宁seo网站建设深圳品牌seo
  • 响应式网站建设济南网络广告图片
  • 热血江湖正版手游官网seo效果最好的是
  • 网站建设方案书阿里云互动营销案例
  • app网站建设销售抖音引流推广一个30元
  • se 网站优化网络营销成功案例有哪些2022
  • 重庆企业建站程序广州四楚seo顾问
  • 移动电商网站开发需求环球网今日疫情消息
  • 南阳哪里做网站比较好如何用手机创建网站
  • 做企业网站的架构图整合营销案例
  • 手机网站弹出导航菜单营销型网站重要特点是
  • 3d建模在线制作网站以品牌推广为目的的广告网络平台
  • 海南网络公司网站建设seo网站的优化流程
  • 石家庄展为网络公司网站如何做优化推广
  • 网站建设上海优化软件有哪些
  • 珠海开发网站公司一诺网络推广公司
  • 网站开发便宜上海网络营销公司
  • 福建泉州网站建设公司大连seo顾问