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 ...
随机推荐
- 【转】git在eclipse中的配置
原文网址:http://www.cnblogs.com/zhxiaomiao/archive/2013/05/16/3081148.html 一_安装EGIT插件 http://download.ec ...
- JS、C#编码解码
escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z encodeURI不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@ ...
- Android客户端调用Asp.net的WebService
Android客户端调用Asp.net的WebService 我来说两句 |2011-11-23 13:39:15 在Android端为了与服务器端进行通信有几种方法:1.Socket通信2.WCF通 ...
- MT9M021/MT9M031总结
MT9M021/MT9m031在低光照度下和捕捉移动场景有非常优异的表现,属于近红外摄像头, S1: Aptina's MT9M021/MT9M031 sensor is capable of a m ...
- php写excel
$this->loadexcel(); $objPHPExcel = new PHPExcel(); $objPHPExcel->getProperties() ...
- 《Linear Algebra and Its Applications》-chaper5-特征值与特征向量-基本概念
基于之前章节的铺垫,我们这里能够很容易的引出特征向量和特征值的概念. 首先我们知道n x n矩阵的A和n维向量v的乘积会得到一个n维的向量,那么现在我们发现,经过计算u=Av,得到的向量u是和v共线的 ...
- 实现自己的脚本语言ngscript之零
正式开始介绍前先扯点没用的. 从小玩basic长大的小朋友大多有一个梦想,就是自己实现一个basic解释器. 不过这里我实现的不是basic,而是一个语法和功能类似javascript的东西. 暂且称 ...
- Django中的Form(二)
一.保存用户输入内容 如果用户输入一张表单提交后出现错误时,会出现重现填写的情况.我们可以把用户输入的信息保存下来,并返回到前台页面,这样用户就无需再次输入. views.py # coding:ut ...
- Linux下开启MySQL的远程连接
今天在用客户端工具远程连接mysql的时候,连接不上,以为是防火墙,关了防火墙后依然打不开,后开在网上查了下原来mysql基于安全考虑root账户一般只能本地访问,但是在开发过程中可能需要打开root ...
- 访问者模式(Visitor)
@@@模式定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下 定义作用于这些元素的新操作. @@@练习示例: 扩展客户管理的功能 @@@示例代码: \patter ...