linux select 网络模型

简介: io模型:   同步IO: 阻塞形式,非阻塞形式(轮询)、信号驱动IO、IO复用(select, poll, epoll);   异步io:aio_read() 典型场景:   1、客户端处理多种IO-------标准io 和网络io(套接字)   2、server端既要处理监听套接字又要...

io模型:

  同步IO: 阻塞形式,非阻塞形式(轮询)、信号驱动IO、IO复用(select, poll, epoll);

  异步io:aio_read()

典型场景:

  1、客户端处理多种IO-------标准io 和网络io(套接字)

  2、server端既要处理监听套接字又要处理已连接的套接字

  3、一个服务器要处理TCP,又要处理UDP

  4、server端要处理多种服务多个协议;

  5、不管是网络套接字还是文件读写描述符均可处理;

  1 #include <stdio.h>
  2 #include <sys/select.h>
  3 #include <sys/time.h>
  4 #include <sys/types.h>
  5 #include <unistd.h>
  6 
  7 #include <netinet/in.h>
  8 #include <sys/socket.h>
  9 #include <string.h>         //bzero()
 10 
 11 int main()
 12 {
 13     int socketfd;
 14     struct sockaddr_in  serv_addr;    //struct socket address internet
 15     int i =0;
 16     /** /usr/include/netinet/in.h
 17      *  #define __SOCKADDR_COMMON(sa_prefix) \
 18      *    sa_family_t sa_prefix##family)
 19      *
 20      *  struct sockaddr_in{
 21      *      _SOCKADDR_COMMON(sin_); //展开宏sa_family_t  sin_family
 22      *      int_port_t sin_port;
 23      *      struct in_addr sin_addr;
 24      *  }
 25      *accept默认会阻塞进程,直到有一个客户连接建立后返回,
 26      *它返回的是一个新可用的套接字,这个套接字是连接套接字。
 27      *此时我们需要区分两种套接字,一种套接字正如accept的参数sockfd,它是监听套接字,
 28      *在调用listen函数之后,一个套接字会从主动连接的套接字变身为一个监听套接字;
 29      *而accept返回是一个连接套接字,它代表着一个网络已经存在的点点连接。
 30      *在调用listen函数之后,一个套接字会从主动连接的套接字变身为一个监听套接字;
 31      *而accept返回是一个连接套接字,它代表着一个网络已经存在的点点连接。
 32      *自然要问的是:为什么要有两种套接字?原因很简单,如果使用一个描述字的话,
 33      *那么它的功能太多,使得使用很不直观,同时在内核确实产生了一个这样的新的描述字.
 34      */
 35     //struct sockaddr_in serv_addr; 
 36     //address family, socket_stream, 0:会自动选择type类型对应的默认协议
 37     socketfd = socket(AF_INET,SOCK_STREAM, 0);
 38     if(socketfd){
 39 
 40     }
 41 
 42     bzero((char*)&serv_addr, sizeof(serv_addr));
 43     serv_addr.sin_family = AF_INET;         //主机字节序
 44     serv_addr.sin_port   = htons(7777);     //网络字节序
 45     serv_addr.sin_addr.s_addr =htonl(INADDR_ANY);   //监听所有地址 
 46 
 47     if(bind(socketfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))){
 48 
 49     }
 50 
 51     listen(socketfd, 100);
 52 
 53     int maxfd;
 54     fd_set allset, rset;
 55     maxfd = socketfd;
 56 
 57     FD_ZERO(&allset);           //将allset清零,使得集合中不含任何fd
 58     FD_SET(socketfd, &allset);  //将socketfd加入allset集合
 59 
 60     int sockfd, clilen, bytes;
 61     struct sockaddr_in cli_addr;
 62     char buffer[256];
 63 
 64     while(1){
 65         rset = allset;
 66        /*select第一个参数表示要检查的文件描述符的个数;比如最大值为5,因为
 67        *文件描述符是从0开始的,所以需要检查0,1,2,3,4,5这六个值;即最大值+1;
 68        */
 69         if(select(maxfd+1, &rset, NULL, NULL, NULL)){
 70 
 71         }
 72 
 73         for(i=0; i<=maxfd; i++){
 74             if(FD_ISSET(i, &rset)){     //一个个来判断是否被置位了
 75                 if(socketfd == i){      //监听套接字
 76                     clilen = sizeof(cli_addr);
 77                     sockfd = accept(socketfd, (struct sockaddr*)&cli_addr, (socklen_t*)&clilen);
 78                     if(sockfd<0){   //error
 79                         perror("accept error \n");
 80                     }
 81                     FD_CLR(i, &rset);   //清零
 82                     maxfd = maxfd>sockfd?maxfd:sockfd;
 83                     FD_SET(sockfd, &allset);
 84 
 85                 }else{                  //通信套接字
 86                     bzero(buffer, 256);
 87                     bytes = recv(i, buffer, 256, 0);
 88                     if(bytes <= 0){     //client端退出
 89                         FD_CLR(i, &allset); //清零
 90                         close(i);
 91                         continue;
 92                     }
 93                     printf("recv msg: %s", buffer);
 94                     send(i, buffer, 255, 0);
 95                 }
 96             }
 97         }
 98     }
 99 
100     return 0;
101 }

 

相关文章
|
6天前
|
C++
基于Reactor模型的高性能网络库之地址篇
这段代码定义了一个 InetAddress 类,是 C++ 网络编程中用于封装 IPv4 地址和端口的常见做法。该类的主要作用是方便地表示和操作一个网络地址(IP + 端口)
104 58
|
2月前
|
域名解析 网络协议 安全
计算机网络TCP/IP四层模型
本文介绍了TCP/IP模型的四层结构及其与OSI模型的对比。网络接口层负责物理网络接口,处理MAC地址和帧传输;网络层管理IP地址和路由选择,确保数据包准确送达;传输层提供端到端通信,支持可靠(TCP)或不可靠(UDP)传输;应用层直接面向用户,提供如HTTP、FTP等服务。此外,还详细描述了数据封装与解封装过程,以及两模型在层次划分上的差异。
440 13
|
2月前
|
网络协议 中间件 网络安全
计算机网络OSI七层模型
OSI模型分为七层,各层功能明确:物理层传输比特流,数据链路层负责帧传输,网络层处理数据包路由,传输层确保端到端可靠传输,会话层管理会话,表示层负责数据格式转换与加密,应用层提供网络服务。数据在传输中经过封装与解封装过程。OSI模型优点包括标准化、模块化和互操作性,但也存在复杂性高、效率较低及实用性不足的问题,在实际中TCP/IP模型更常用。
273 10
|
6天前
基于Reactor模型的高性能网络库之Poller(EpollPoller)组件
封装底层 I/O 多路复用机制(如 epoll)的抽象类 Poller,提供统一接口支持多种实现。Poller 是一个抽象基类,定义了 Channel 管理、事件收集等核心功能,并与 EventLoop 绑定。其子类 EPollPoller 实现了基于 epoll 的具体操作,包括事件等待、Channel 更新和删除等。通过工厂方法可创建默认的 Poller 实例,实现多态调用。
133 60
|
6天前
基于Reactor模型的高性能网络库之Channel组件篇
Channel 是事件通道,它绑定某个文件描述符 fd,注册感兴趣的事件(如读/写),并在事件发生时分发给对应的回调函数。
121 60
|
6天前
|
安全 调度
基于Reactor模型的高性能网络库之核心调度器:EventLoop组件
它负责:监听事件(如 I/O 可读写、定时器)、分发事件、执行回调、管理事件源 Channel 等。
106 57
|
6天前
基于Reactor模型的高性能网络库之时间篇
是一个用于表示时间戳(精确到微秒)**的简单封装类
96 57
|
2天前
|
网络协议 算法 Java
基于Reactor模型的高性能网络库之Tcpserver组件-上层调度器
TcpServer 是一个用于管理 TCP 连接的类,包含成员变量如事件循环(EventLoop)、连接池(ConnectionMap)和回调函数等。其主要功能包括监听新连接、设置线程池、启动服务器及处理连接事件。通过 Acceptor 接收新连接,并使用轮询算法将连接分配给子事件循环(subloop)进行读写操作。调用链从 start() 开始,经由线程池启动和 Acceptor 监听,最终由 TcpConnection 管理具体连接的事件处理。
21 2
|
2天前
基于Reactor模型的高性能网络库之Tcpconnection组件
TcpConnection 由 subLoop 管理 connfd,负责处理具体连接。它封装了连接套接字,通过 Channel 监听可读、可写、关闭、错误等
16 1
|
2月前
|
安全 网络协议 Linux
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
87 18