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> ...
随机推荐
- HDU 4745 Two Rabbits 区间dp_回文序列
题目链接: http://blog.csdn.net/scnu_jiechao/article/details/11759333 Two Rabbits Time Limit: 10000/5000 ...
- 阅读 DPDK 中文论文两则
基于DPDK的高效数据包捕获技术分析与应用 本文应用场景 网络安全领域的数据包捕获技术,对系统有高性能需求,要在短时间内成功收集.分析.处理大量数据,实时捕获效率低下. 旧有传统数据包处理机制 BPF ...
- Good Time 冲刺 一
2018/6/14 我们组之前没有开发小程序的经验,所以在尝试中不断探索与学习.在完成小程序的初步注册和界面完善后,我们组开始进行开发任务. 1.1成员简述: 王怡镔:“今天主要学习小程序开发知识及相 ...
- NTP同步网络时间
为什么要同步网络时间呢,这是由于树莓派没有RTC和后备电池,不能像PC机那样关机之后仍可以走时. NTP对时步骤: 1 安装ntpdate sudo apt-get install ntpdate s ...
- win10频繁提示证书即将过期怎么办
最近几天每次开机都会提示许可证即将过期 ”Windows+R”打开“运行”窗口,输入“slmgr.vbs -xpr”并点击“确定”,弹出的窗口确实显示过期时间在本月1.29过期 百度各种激活方法后,发 ...
- 第七周PSP&进度条
团队项目PSP 一.表格: C类型 C内容 S开始时间 E结束时间 I时间间隔 T净时间(mins) 预计花费时间(mins) 讨论 讨论beta阶段任务 10:00 12:30 28 270 ...
- [转帖学习]Howto Shrink a Thin Provisioned Virtual Disk (VMDK)
Howto Shrink a Thin Provisioned Virtual Disk (VMDK) Posted by fgrehl on November 24, 2014Leave a com ...
- SQL有三个类型的索引,唯一索引 不能有重复,但聚集索引,非聚集索引可以有重复
重要: (1) SQL如果创建时候,不指定类型那么默认是非聚集索引 (2) 聚集索引和非聚集索引都可以有重复记录,唯一索引不能有重复记录. (3) 主键 默认是加了唯一约束的聚集索引,但是也可以在主键 ...
- 【bzoj5084】hashit 广义后缀自动机+树链的并+STL-set
题目描述 你有一个字符串S,一开始为空串,要求支持两种操作 在S后面加入字母C 删除S最后一个字母 问每次操作后S有多少个两两不同的连续子串 输入 一行一个字符串Q,表示对S的操作 如果第i个字母是小 ...
- JAVA相关概念(一)
依赖注入和控制反转 首先,这两个词是同一个概念的不同角度的说法,依赖注入感觉是对描述了如何实现,而控制反转则像是描述了一种思想. 依赖注入的流行可以说是由spring的流行带动的,只要是做过sprin ...