linux下多路复用模型之Select模型

Linux关于并发网络分为Apache模型(Process per Connection (进程连接) ) 和TPC , 还有select模型,以及poll模型(一般是Epoll模型)

Select模型极其作用:这文章讲述的很好,没必要重述已有的东西,就直接给链接

http://blog.csdn.net/turkeyzhou/article/details/8609360

我的理解:

 1 /* According to POSIX.1-2001 */
 2 #include <sys/select.h>
 3
 4 /* According to earlier standards */
 5 #include <sys/time.h>
 6 #include <sys/types.h>
 7 #include <unistd.h>
 8
 9 int select(int nfds, fd_set *readfds, fd_set *writefds,
10 fd_set *exceptfds, struct timeval *timeout);
11
12 void FD_CLR(int fd, fd_set *set);
13 int FD_ISSET(int fd, fd_set *set);
14 void FD_SET(int fd, fd_set *set);
15 void FD_ZERO(fd_set *set);

对于

   int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);        第一个参数 nfds:  第n个文件id的编号   (linux下,一切皆文件)  需要注意的是: nfds = fd+1 (fd 为 FD_SET中的fd)        第二个参数:  fd_set *readfds   读取文件编号,如果不需要读取的话 可以设置为NULL        第三 ,四个参数:  同上        第五个参数:为一个定义超时的结构体
1        struct timeval {
2                time_t         tv_sec;     /* seconds */
3                suseconds_t    tv_usec;    /* microseconds */
4            };

该结构用来设定多少时间为超时 ,比如

struct timeval ss ;
   ss.tv_sec  =3;
   ss.tv_usec =0;
//表示设定为3秒后为超时,select将会返回0
对于下面这几个函数:

1 void FD_CLR(int fd, fd_set *set);

用来清除fd的fd_set  ,比如fd为5  ,则表示set集中所有设定等于5的fd_set 都将被清除

1 int FD_ISSET(int fd, fd_set *set);

判断是否set 与fd是否绑定,如果没有绑定,则返回false,如果绑定了则返回True

void FD_SET(int fd, fd_set *set);

将fd值 和set绑定

void FD_ZERO(fd_set *set);

将set集全部清除

简单的例子:

判断是否有数据输入,有则直接打印出来

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<sys/select.h>
 4 #include<unistd.h>
 5 #include<sys/time.h>
 6 #include<sys/types.h>
 7 #define maxn 6
 8 #define EXIT_FAILURE  -1
 9 #define EXIT_SUCCESS   0
10
11 int main(int argc , char * argv []){
12
13    fd_set mtfd ;
14    int ffd =0;
15    struct timeval  outtime ;
16    int retval  ;
17    char redbuf[maxn];
18
19    FD_ZERO(&mtfd);
20    FD_SET(ffd , &mtfd);
21
22 // wait up to 5.5 s
23    outtime.tv_sec = 5 ;
24    outtime.tv_usec = 500 ;
25    retval = select(ffd+1 , &mtfd ,NULL , NULL , &outtime);
26    if(-1 == retval )
27    {
28      printf("error happened ! %d \n" ,__LINE__ );
29      return EXIT_FAILURE ;
30    }
31    else if(0 == retval ){
32       printf(" timeout !!  %d \n" ,__LINE__ );
33      return  EXIT_FAILURE ;
34     }
35    //means that is good !
36
37      printf("retval  =  %d \n", retval);
38
39     if( FD_ISSET(ffd , &mtfd) ){
40
41         memset(redbuf ,0 , sizeof(redbuf));
42         printf("reading ... !! ");
43        // read(1 , redbuf ,sizeof(redbuf) ); //use the sys func
44        fread(redbuf , sizeof(redbuf) ,ffd+1 , stdin );
45 }
46     //  fwrite(redbuf ,strlen(redbuf) , 1 , stdout );
47    //  write(1 , redbuf , strlen(redbuf));
48      printf("buf = %s    buf_len = %d \n" , redbuf , strlen(redbuf));
49
50     return EXIT_SUCCESS ;
51 }

makefile文件:

 1 .SUFFIXES: .o.c
 2 CC =gcc
 3 SRC = Se_keyboard.c
 4 OBJ = $(SRC: .c =.o)
 5 BIN = Se_keyboard
 6
 7
 8 .PHONY: start
 9 start:  $(OBJ)
10         $(CC) -o $(BIN) $(OBJ)
11 .o.c: $(SRC)
12         $(CC) -g -Wall [email protected] -c  $<
13 .PHONY: clean
14 clean:
15         rm -f $(OBJ)                    

虽然知道这么多,但是还是觉得Select并没有什么作用。

Select一般是和Socket搭配使用,相当于线程池的效果,但是线程池有缺点,详情看这儿:

http://blog.csdn.net/tianmohust/article/details/6677985

http://blog.csdn.net/xifeijian/article/details/17385831

关于Select的原理图:

首先来看下一对一的socket的c/s模式

关于socket的一对一的详解

http://www.cnblogs.com/gongxijun/p/4592864.html

看完这个之后,我们现在可以来看看这个图:

时间: 2024-10-11 23:47:36

linux下多路复用模型之Select模型的相关文章

Linux 下 简单客户端服务器通讯模型(TCP)

原文:Linux 下 简单客户端服务器通讯模型(TCP) 服务器端:server.c #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<sys/socket.h> #include<sys/types.h> #include <stdio.h> #include <unistd.h> #inclu

epoll模型与select模型的区别

Nginx  --->epoll模型 Apache --->select模型 处理大量连接的读写时,Apache所采用的select网络I/O模型比较低,用两个通俗的比喻来解释二者的区别: 第一个比喻: 例如你在大学读书,住的宿舍楼有很多房间,你的朋友要来找你,select版宿管大妈就会 带着你的朋友到各个房间挨个去找,直到找到为止.而epoll版宿管大妈会先记下每位入住同学的房间号码,当你朋友来找你时,只需告诉你的朋友你住在哪个房间?不用亲自带着你的朋友满宿舍的找.如果同时来了100个人,都

Socket I/O模型之select模型

socket网络编程中有多种常见的I/O模型: 1.blocking阻塞 2.nonblocking非阻塞 3.I/O multiplexing复用 4.signal driven 5.asynchronous I/O异步 这里我们主要介绍I/O multiplexing模型中的代表select模型:select模型将多个套接字放在一个集合里,然后统一检查这些套接字的状态,每次调用套接字后会更新这些套接字的状态,然后做判断,如果套接字可读,就执行read操作.这样就巧妙地避免了阻塞,达到同时处理

Linux下的五种IO模型

5种IO模型 Linux下五种IO模型 (1)阻塞I/O:什么都不干,导致应用程序阻塞,等待数据准备好,如果数据没有准备好,一直阻塞,等数据准备好了从内核拷贝到用户空间 (2)非阻塞I/O:把一个套接字接口设置为非阻塞,告诉内核,当所请求的IO无法完成时,不要将进程睡眠,而是返回一个错误,这样IO操作函数会不断地测试数据是否准备好,如果没有准备好 ,继续测试,直到准备好为止 (3)I/O复用(select epoll):select或epoll会使进程阻塞,但是和阻塞IO不同的是,这两个函数可以

Linux下多进程服务端客户端模型一(单进程与多进程模型)

本文将会简单介绍Linux下如何利用C库函数与系统调用编写一个完整的.初级可用的C-S模型. 一.基本模型: 1.1   首先服务器调用socket()函数建立一个套接字,然后bind()端口,开始listen()监听,此时,套接字变成了被动的套接字,用于侦听客户端的请求.然后accept(),开始阻塞监听客户端的请求. 1.2   客户端以服务端的参数为参数,用socket()建立套接字,然后connect()连接服务端. 1.3  服务端收到连接请求,accept()返回一个标识符,继续执行

关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记.

说明 为何要写这篇文章 ,之前看过阿二的梦想船的<Poco::TCPServer框架解析> http://www.cppblog.com/richbirdandy/archive/2010/09/10/123994.html 无奈代码太多,看起繁琐.所以 准备 以流程图简化,便于理解.也方便自己以后使用. 本文内容 是基于window api分析的. 本文的poco是1.4.6p4 (2014-04-18)版本的. 虽然现在poco版本是1.6 但调用改动不大. poco下载地址:http:/

Winsock IO模型之select模型

之所以称其为select模型是因为它主要是使用select函数来管理I/O的.这个模型的设计源于UNIX系统,目的是允许那些想要避免在套接字调用上阻塞的应用程序有能力管理多个套接字. int select( int nfds,                                                 // 忽略,仅是为了与Berkeley套接字兼容 fd_set* readfds,                                  // 指向一个套接字集合,

Linux下多路复用IO接口epoll/select/poll的区别

select比epoll效率差的原因:select是轮询,epoll是触发式的,所以效率高. Select: 1.Socket数量限制:该模式可操作的Socket数由FD_SETSIZE决定,内核默认32*32=1024. 2.操作限制:通过遍历FD_SETSIZE(1024)个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍. Poll: 1.Socket数量几乎无限制:该模式下的Socket对应的fd列表由一个数组来保存,大小不限(默认4k). 2.操作限制:同Select.

Linux下多进程服务端客户端模型二(粘包问题与一种解决方法)

一.Linux发送网络消息的过程 (1) 应用程序调用write()将消息发送到内核中 ( 2)内核中的缓存达到了固定长度数据后,一般是SO_SNDBUF,将发送到TCP协议层 (3)IP层从TCP层收到数据,会加上自己的包头然后发送出去.一般分片的大小是MTU(含IP包头),而IPV4下IP的包头长度为40,而IPV6下为60,因此,TCP中分片后,有效的数据长度为MSS = MTU - 40 或 MSS = MTU -60 (4)最终经过其他层的包装,发送到公网上,跑来跑去,这时候,你的数据