select()函数
select(),确定一个或多个套接口的状态,本函数用于确定一个或多个套接口的状态,对每一个套接口,调用者可查询它的可读性、可写性及错误状态信息,用fd_set结构来表示一组等待检查的套接口,在调用返回时,这个结构存有满足一定条件的套接口组的子集,并且select()返回满足条件的套接口的数目。有一组宏可用于对fd_set的操作,这些宏与Berkeley Unix软件中的兼容,但内部的表达是完全不同的。
简述
注释
返回值
错误代码
调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
//下面是示例代码: //代码是服务器TCP模型,采用多路复用的select函数实现了循环的监听并接受客户端的功能,其中也包含了上传下载的功能*/ #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/socket.h> #include<string.h> #include<netinet/in.h> #include<sys/ioctl.h> #include<sys/stat.h> #include<fcntl.h> #include<sys/types.h> #include<dirent.h> int main() { struct sockaddr_in seraddr,cliaddr; int listenfd,connfd,fd1,fd2,n,m,l,port; char user[20],buf[4096]; fd_set readfds,tmpfds; //岗哨监控集合 socklen_t addrlen; DIR *dr; struct dirent *file; printf ( "请输入需要设定的服务器名称:" ); scanf ( "%s" ,user); printf ( "请输入需要设定的服务器端口:" ); scanf ( "%d" ,&port); getchar (); if ((listenfd=socket(AF_INET,SOCK_STREAM,0))<0) { perror ( "创建失败" ); exit (-1); } /*开始设定服务器的参数地址类型,IP,PORT*/ memset (&seraddr,0, sizeof (seraddr)); //将服务器的初值空间清空,防止转化过程有影响 seraddr.sin_family=AF_INET; seraddr.sin_port=htons(port); //将得到的本地端口转换为网络字节序 seraddr.sin_addr.s_addr=htonl(INADDR_ANY); //将得到的ip地址字符串转换为网络字节序的ip地址数值 if ((bind(listenfd,( struct sockaddr*)&seraddr, sizeof (seraddr))<0)) { perror ( "绑定失败" ); exit (-1); } printf ( "绑定创建\n" ); if ((connfd=listen(listenfd,50))<0) { perror ( "监听失败" ); exit (-1); } printf ( "开始监听\n" ); FD_ZERO(&readfds); //初始化文件集 FD_SET(listenfd,&readfds); //将需要监视的listenfd放入readfds集中 while (1) //循环监听 { int nread,n; tmpfds=readfds; //将监视集传递给临时的监视集中,防止后续的操作修改了监视集 if (select(FD_SETSIZE,&tmpfds,NULL,NULL,NULL)<0) //设置监视,监视tmpfds内的子fd变化,发生变化的将会被保留在tmpfds中 { perror ( "监视未成功" ); exit (-1); } for (fd1=0;fd1<FD_SETSIZE;fd1++) //循环找在最大范围内的fd1 { if (FD_ISSET(fd1,&tmpfds)) //查找是否fd在tmpfds里面 { if (fd1==listenfd) //判定fd等于监听fd,即监听fd在监视过程中出现变化被发现 { addrlen= sizeof (cliaddr); connfd=accept(listenfd,( struct sockaddr*)&cliaddr,&addrlen); //开始接收客户 FD_SET(connfd,&readfds); //将connfd加入监视集,监视接入的变化 printf ( "接入新的连接\n" ); } else { ioctl(fd1,FIONREAD,&nread); //测试在fd中还有nread个字符需要读取 if (nread==0) //如果需要读取的数据为0,则关闭检测出来的fd1,并且从监视中移除 { close(fd1); FD_CLR(fd1,&readfds); printf ( "移除\n" ); } else //如果可读数据不为0,则读出来 { int i; char *p=NULL,*q=NULL; n=read(fd1,buf,nread); buf[n]=0; p=buf; if (( strncmp (p, "-get" ,4)==0)) { q=p+5; printf ( "客户下载文件>%s" ,q); if ((fd2=open(q,O_RDONLY))<0) perror ( "打开文件错误" ); while ((m=read(fd2,buf,4096))>0) { write(connfd,buf,m); } bzero(buf, sizeof (buf)); close(fd1); close(fd2); FD_CLR(fd1,&readfds); } if (( strncmp (p, "-up" ,3)==0)) { q=p+4; printf ( "客户上传文件%s\n" ,buf+4); if ((fd2=open(q,O_CREAT | O_WRONLY | O_APPEND ,0666))<0) { perror ( "打开文件写入失败" ); } while ((m=read(connfd,buf,128))>0) { printf ( "%s" ,buf); write(fd2,buf,m); } bzero(buf, sizeof (buf)); close(fd1); close(fd2); FD_CLR(fd1,&readfds); } if (( strncmp (p, "-ls" ,3)==0)) { q=p+4; printf ( "客户查看文件……" ); if ((dr=opendir(q))==NULL) perror ( "打开目录失败" ); while ((file=readdir(dr))!=NULL) { printf ( "%s " ,file->d_name); write(connfd,file->d_name, sizeof (file->d_name)); } close(fd1); close(connfd); closedir(dr); FD_CLR(fd1,&readfds); } printf ( "从客户收取的信息:%s\n" ,buf); } } } //end if 0 } //end for 0 } //end while0 exit (0); } //end main |
相关参考
事件用法
select()函数的更多相关文章
- (十二)select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET
select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型,原型:int select(int maxfd,fd_set *rdset ...
- select 函数1
Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect.accept.recv或recvfrom这样的阻塞程序( ...
- select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET
http://hi.baidu.com/%B1%D5%C4%BF%B3%C9%B7%F0/blog/item/e7284ef16bcec3c70a46e05e.html select函数用于在非阻塞中 ...
- PHP Socket实现websocket(四)Select函数
int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout); /* ...
- IO复用与select函数
socket select函数的详细讲解 select函数详细用法解析 http://blog.chinaunix.net/uid-21411227-id-1826874.html linu ...
- I/O多路复用——select函数与poll函数
1 区别 同:(1)机制类似,本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理.(2)包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就 ...
- select函数
select函数: http://baike.baidu.com/view/3421856.htm select函数 目录 概况 操作程序 宏解释 socket读写 概况 select()的机制中 ...
- select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET(转)
select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型, 原型: int select(int maxfd,fd_set *rds ...
- 阻塞、非阻塞的概念和select函数的阻塞功能
其它文档: http://www.cnitblog.com/zouzheng/archive/2010/11/25/71711.html (1)阻塞block 所谓阻塞方式block,顾名思义 ...
- select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET (转)
select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型,原型: #include <sys/time.h> ...
随机推荐
- Task 4.5 求二维数组中的最大连通子数组之和
任务:输入一个二维整形数组,数组里有正数也有负数. 求所有子数组的和的最大值.要求时间复杂度为O(n). 1.设计思想:因为用之前的解决子数组最大和的问题的思路一直没能解决这个问题,后来看到同学使用将 ...
- Task 6.3 场景调研
1.背景: (1)典型用户:信息1303班王银凤 (2)用户的需求/迫切需要解决的问题:她们宿舍上网一直使用的是外网,一年400的一种“套餐”.这种是按小时计算的,在校的时间平均下来一天可以用7 . ...
- Java导出引用jar包的文件
安装Eclipse打包插件Fat Jar 方案一对于含有较多第三方jar文件或含有第三方图片资源等就显得不合适,太繁琐.这时可以使用一个打包的插件-Fat Jar. Fat Jar ...
- C#窗体随机四则运算 (第四次作业)
---恢复内容开始--- 增量内容:1)处理用户的错误输入,比如输入字母或符号等,处理除法运算中分母为0的情况,处理结果为负数的情况,保证是小学水平不出现负数,比如不能出现5-8=-3这种情况:2)用 ...
- shiro+springmvc 都使用缓存
基于涛哥shiro案例16 的这时候要配置service方法的缓存 在spring-config.xml添加 <context:annotation-config /> <cache ...
- CANopen 基础
1. TPDO和RPDO都是针对从站来说的,协议上没有有讲任何一个关于主站的概念,协议就只是定义从站,没有定义主站任何东西.TPDO:从站->主站RPDO:主站->从站 2. PDO的CO ...
- Week3结对项目-数独游戏
题目要求 1)在文章开头给出Github项目地址.(1') 2)在开始实现程序之前,在下述PSP表格记录下你估计将在程序的各个模块的开发上耗费的时间.(0.5') 3)看教科书和其它资料中关于Info ...
- XLSReadWriteII5使用示例
之前一直是使用XLSReadWriteII4,今天更新到XLSReadWriteII5,测试了一下,发现一些操作变化比较大,现将XLSReadWriteII5的使用示例写一下,以下是代码和生成的exc ...
- D3.js 入门学习(二) V4的改动
//d3.scan /* 新的d3.scan方法对数组进行线性扫描,并根据指定的比较函数返回至少一个元素的索引. 这个方法有点类似于d3.min和d3.max. 而d3.scan可以得到极值的索引而不 ...
- ini_set
1.ini_set函数是设置选项中的值,在执行函数后生效,脚本结束的时候,这个设置也失效.ini_set 用于更改配置文件的配制,次更改仅用于此脚本的执行.不是所有的选项都能被改函数设置的. 2.in ...