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