socket网络编程实现并发服务器——IO多路复用

一 五种网络I/O模型

在Linux下进行网络编程时,服务器端编程经常需要构造高性能的IO模型,常见的IO模型有五种:
(1)同步阻塞IO
(2)同步非阻塞IO(Non-blocking IO)
在这里插入图片描述
(3)IO多路复用(IO Multiplexing)
:IO多路复用模型是建立在内核提供的多路分离函数select基础之上的,使用select函数 可以避免同步非阻塞IO模型中轮询等待的问题,此外poll、epoll都是这种模型。
在这里插入图片描述
(4) 信号驱动IO(signal driven IO)
(5)异步IO(Asynchronous IO)

各服务器源代码:https://gitee.com/constructorvirgil/lingyun_apue/tree/master/yangjianing

二 多路复用–select

select()函数允许进程指示内核等待多个事件(文件描述符)中的任何一个发生,并只在有一个或多个事件发生或经历一段指定时 间后才唤醒它,然后接下来判断究竟是哪个文件描述符发生了事件并进行相应的处理。

#include <sys/select.h>
#include <sys/time.h>
    
 struct timeval   
 {
     
       long tv_sec;   //seconds   
       long tv_usec;  //microseconds 
 };
       FD_ZERO(fd_set* fds)           //清空集合 
       FD_SET(int fd, fd_set* fds)    //将给定的描述符加入集合 
       FD_ISSET(int fd, fd_set* fds)  //判断指定描述符是否在集合中
       FD_CLR(int fd, fd_set* fds)    //将给定的描述符从文件中删除  

看一下函数原型

int select(int max_fd, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout);

1 第一个参数max_fd指待测试的fd的总个数,它的值是待测试的最大文件描述符加1
2 中间三个参数readset、writeset和exceptset指定要让内核测试读、写和异常条件的fd集合,如果不需要测试的可以设置为 NULL;
3 最后一个参数是设置select的超时时间,如果设置为NULL则永不超时

下面是使用select()多路复用实现的服务器端示例代码:(只贴出主要部分)

for(i=0; i<ARRAY_SIZE(fds_array); i++)
    {
   
	    fds_array[i] = -1;   //说明该位置为空

    }
    fds_array[0]=listenfd;

    while (1)
    {
   
	    FD_ZERO(&rdset);   //清零
	    for(i=0; i< ARRAY_SIZE(fds_array);i++)  //遍历该数组
	    {
   
		    if (fds_array[i]<0)
	            {
   
			    continue;
                    }
		     maxfd = fds_array[i]>maxfd ? fds_array[i] : maxfd;        
	   	     FD_SET(fds_array[i], &rdset); 
	    }
    }


    rv = select(maxfd+1, &rdset, NULL, NULL, NULL); 
    if (rv < 0)
    {
   
	    printf("select failure: %s\n",strerror(errno));
	    break ;
    } 
    else if (rv == 0)
    {
   
	    printf("select get timeout\n");
	    continue;
    }

    if (FD_ISSET(listenfd, &rdset))  //是否是新客户端链接
    {
   
	    if(connfd = accept(listenfd, (struct sockaddr *)NULL,NULL) < 0)
	    {
   
                    printf("accept new client failure : %s\n",strerror(errno));
		    return -4;
	    }
    

    found = 0;
    for(i=0; i<ARRAY_SIZE(fds_array);i++)
    {
   
            
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值