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 ...
随机推荐
- bzoj1391
很像最大权闭合子图的题目s向每个工作连边,流量为收益每个工序,由工作i向对应机器连边,流量为租用费每个机器向t连边,流量为购买费显然跑最小割,ans=总收益-mincut ; type node=re ...
- UVA10054 The Necklace
UVA10054 The Necklace 链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18806 [思路] 欧拉回路 ...
- expect远程登陆hw交换机--测试通过1
#!/bin/bash #connect_the_hw_switch #by osx1260@.com swip=172.16.56.2 swport= swpasswd='yourswpasswd' ...
- Subversion/Git/ReviewBoard工作流程
根据My (work)Git Workflow进行修改,在 Windows下进行测试,http://mojodna.net/2009/02/24/my-work-git-workflow.html 目 ...
- java传递json数据到前台jsp
在数据传输流程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象,所以,JSON对象和JSON字符串之间的相互转换是关键.例如: JSON字符串: var str1 = '{ &q ...
- java读取图片的(尺寸、拍摄日期、标记)等EXIF信息
1.metadata-extractor是 处理图片EXIF信息的开源项目,最新代码及下载地址:https://github.com/drewnoakes/metadata-extractor 2.本 ...
- c++ 流基本概念
前言 在程序经常实现数据的输入和输出,c++通过一种称为流(stream)的机制提供了更为精良的输入和输出方法.流是一种灵活且面向对象的I/o方法. 根据操作对象不同分为文件流.字符串流.控制台流. ...
- python 分支 循环
一 python 知识点 1.变量(标签): a(变量名) = '字符串'or 数字 (整形和浮点型) a相当于变量名的标签 如: a = ...
- 提高你的Java代码质量吧:正确使用String、StringBuffer、StringBuilder
一.建议 CharSequence接口有三个实现类与字符串相关:String.StringBuffer.StringBuilder,虽然它们都与字符串相关,但是其处理机制不同. 根据不同的场景,建议 ...
- SQL字符串处理函数大全
select语句中只能使用sql函数对字段进行操作(链接sql server),select 字段1 from 表1 where 字段1.IndexOf("云")=1;这条语句不对 ...