I/O多路转接之select

FD_CLR(inr fd,fd_set* set);用来清除描述词组set中相关fd 的位
FD_ISSET(int fd,fd_set *set);用来测试描述词组set中相关fd 的位是否为真
FD_SET(int fd,fd_set*set);⽤用来设置描述词组set中相关fd的位

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<assert.h>
#include<unistd.h> int fds[];
const int back_log=;
void usage(char* argv)
{
printf("%s:[ip][port]\n",argv);
}
int start_up(char* ip,int port) //创建一个套接字,绑定,检测服务器
{
//sock
int sock=socket(AF_INET,SOCK_STREAM,); //创建套接字
if(sock<)
{
perror("sock");
exit();
}
struct sockaddr_in local; //本地 sockaddr_in 结构体
local.sin_port=htons(port);
local.sin_family=AF_INET;
local.sin_addr.s_addr=inet_addr(ip); //bind
if(bind(sock,(struct sockaddr*)&local,sizeof(local))<) //绑定
{
perror("bind");
exit();
}
//listen
if(listen(sock,back_log)<) //检测服务器
{
perror("sock");
exit();
}
return sock;
}
int main(int argc,char* argv[])
{
if(argc!=) //检测参数个数是否正确
{
usage(argv[]);
exit();
}
int port=atoi(argv[]);
char* ip=argv[]; int done=;
int new_sock=-;
int listen_sock=start_up(ip,port); //创建一个绑定了本地 ip 和端口号的套接字描述符
struct sockaddr_in client;
socklen_t len=sizeof(client); int max_fd = -; //文件描述符最大值
fd_set _reads; //_reads文件描述符集
fd_set _writes; //_writes文件描述符集 int i=;
int fds_num=sizeof(fds)/sizeof(fds[]); //文件描述符的数组
for(i=;i<fds_num;i++) //初始化文件描述符数组
{
fds[i]=-;
}
fds[]=listen_sock; //将listen_sock写入文件描述符数组之中 while(!done)
{
FD_ZERO(&_reads); //每次循环把_reads,_writes初始化(输入、输出 参数)
FD_ZERO(&_writes);
struct timeval _timeout={,}; //设置等待时间
for(i=;i<fds_num;i++)
{
if(fds[i]>)
{
FD_SET(fds[i],&_reads); //select要监听的套接字描述符 加到文件描述符集中
if(fds[i]>max_fd)
{
max_fd=fds[i];
}
}
}
switch(select(max_fd+,&_reads,&_writes,NULL,&_timeout)) //_reads,_writes,_timeout 输入,输出参数
{
case : //select输出0 ,表示监听超时
printf("timeout\n");
break;
case -: //select出错
perror("select");
break;
default: //_reads(输入输出型参数)文件描述符集中有 OK 的
{
for(i=;i<fds_num;i++)
{
if(fds[i]==listen_sock&&FD_ISSET(fds[i],&_reads)) //select 关注的迎宾 socket 描述符已就绪
{
new_sock=accept(listen_sock,(struct sockaddr*)&client,&len); //创建新的 socket 描述符 if(new_sock<)
{
perror("new_sock");
continue;
}
printf("get connection...%ld\n",new_sock);
for(i=;i<fds_num;i++) //将新的 socket 描述符安排在数组中未被占用的最小位置
{
if(fds[i]==-)
{
fds[i]=new_sock;
break;
}
}
if(i==fds_num) //文件描述符个数已达到最大值则忽略
{
close(new_sock);
}
} else if(fds[i]>&&FD_ISSET(fds[i],&_reads)) //select 关注的普通的 socket 描述符
{
char buf[];
ssize_t _s=read(fds[i],buf,sizeof(buf)-);
if(_s>)
{
buf[_s]='\0';
printf("%s\n",buf);
}
else if(_s==)
{
fds[i] = -; //在 _read 文件描述符数组中去掉
printf("client closed\n");
}
else
{
perror("read");
}
}
else
{}
}
}
}
}
return ;
}
I/O多路转接之select的更多相关文章
- Linux下I/O多路转接之select --fd_set
fd_set 你终于还是来了,能看到这个标题进来的,我想,你一定是和我遇到了一样的问题,一样的疑惑,接下来几个小时,我一定竭尽全力,写出我想说的,希望也正是你所需要的: 关于Linux下I/O多路转接 ...
- UNIX环境高级编程——I/O多路转接(select、pselect和poll)
I/O多路转接:先构造一张有关描述符的列表,然后调用一个函数,直到这些描述符中的一个已准备好进行I/O时,该函数才返回.在返回时,它告诉进程哪些描述符已准备好可以进行I/O. poll.pselect ...
- 【Nginx】I/O多路转接之select、poll、epoll
当需要读两个以上的I/O的时候,如果使用阻塞式的I/O,那么可能长时间的阻塞在一个描述符上面,另外的描述符虽然有数据但是不能读出来,这样实时性不能满足要求,大概的解决方案有以下几种: 1.使用多进程或 ...
- UNP——第六章,多路转接IO——select
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); ...
- 高级I/O之I/O多路转接——pool、select
当从一个描述符读,然后又写到另一个描述符时,可以在下列形式的循环中使用阻塞I/O: ) if (write(STDOUT_FILENO, buf, n) != n) err_sys("wri ...
- IO多路转接select和poll
select IO多路复用的设置方法与信号的屏蔽有点相似: 信号屏蔽需要先设定一个信号集, 初始化信号集, 添加需要屏蔽的信号, 然后用sigprocmask设置 IO多路转接需要先设定一个文件描述符 ...
- select函数与I/O多路转接
select函数与I/O多路转接 相作大家都写过读写IO操作的代码,例如从socket中读取数据可以使用如下的代码: while( (n = read(socketfd, buf, BUFSIZE) ...
- select 与 I/O多路转接
参考博客:http://blog.sina.com.cn/s/blog_607072980102uxcw.html I/0多路转接: 描述符表示某个I/O.构造一张有关描述符的数据表,调用select ...
- I/O多路转接 --- UNIX环境高级编程
I/O多路转接技术:先构造一张有关描述符的列表,然后调用一个函数,知道这些描述符中的一个已准备好进行I/O时,给函数才返回.在返回时,它告诉进程哪些描述符已准备好可以进行I/O. poll.selec ...
随机推荐
- Hibernate(五)一对一单向关联映射
上次的博文中 Hibernate从入门到精通(四)基本映射我们已经讲解了一下基本映射和相关概念,接下来 我们会讲稍微复杂点的映射——关系映射. 关系映射分类 关系映射即在基本映射的基础上处理 多个相关 ...
- Jdk5.0新特性
增强for循环:foreach语句,foreach简化了迭代器. 格式:// 增强for循环括号里写两个参数,第一个是声明一个变量,第二个就是需要迭代的容器 for( 元素类型 变量名 : Colle ...
- vijosP1071 新年趣事之打牌
vijosP1071 新年趣事之打牌 链接:https://vijos.org/p/1071 [思路] 01背包+路径输出. 用d[][]记录[][]可转移的数目,>=2则输出-1,0输出0,否 ...
- sqlplus乱码
使用SecureCRT或是pietty_ch连接到一台安装有Oracle DB 10g的RHEL4.2的机器,linux使用的shell是默认的bash. 在bash提示符下,使用Del键或者Back ...
- Corn Fields - POJ 3254(状态压缩)
题目大意:有一个M*N的牧场,G(i, j) = 1表示这块地营养丰富,可以喂养牛,等于0表示贫瘠,不能喂养牛,所有的牛都讨厌与别的牛相邻,求有多少种放置牛的方式. 分析:算是炮兵那个题的弱化版吧,先 ...
- xCode里面设置NSZombieEnabled定位错误
打开product ->scheme->Edit scheme
- unique mapped reads
就是指唯一比对的reads 现在人们已经开始避免使用unique mapped reads这个概念了,而转向使用mapq值来保留高质量的比对结果.因为mapq值反应了一组比对结果发生的可能性,MapQ ...
- JS方法在iframe父子窗口间的调用
本文向大家简单介绍一下iframe父子窗口间JS方法调用,JavaScript 被数百万计的网页用来改进设计.验证表单.检测浏览器.创建cookies,以及更多的应用,希望本文介绍对你有所帮助. if ...
- httpd cgi程序配制+.py .cgi执行
vi /etc/httpd/conf/httpd.conf httpd默认首页配制: DirectoryIndex index.html index.html.var 首页的位置定义: Docume ...
- iOS-UIControls介绍
iOS-UIControls类介绍 UIControl的继承关系 UIControl是 UIKit中UISwitch(开关).UIButton(按钮).UISegmentedControl(分段控件) ...