unix 网络编程 select 讲解
来源:互联网 发布:火车采集软件 编辑:程序博客网 时间:2024/06/05 10:05
1. 首先要将用于监听的socket设置为非阻塞的端口,这里我们就会用到setsockopt()函数:
int setsockopt(int s, int level, int optname, void* optval, socklen_t* optlen);
这里我们要涉及到一个结构:
struct timeval
{
time_t tv_sec;
time_t tv_usec;
};
这里第一个域的单位为秒,第二个域的单位为微秒。
struct timeval tv_out;
tv_out.tv_sec = 1;
tv_out.tv_usec = 0;
填充这个结构后,我们就可以以如下的方式调用这个函数:
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv_out, sizeof(tv_out));(具体参数可以man一下,或查看MSDN)
这样我们就设定了recv()函数的超时机制,当超过tv_out设定的时间而没有数据到来时recv()就会返回0值。
2. 我们要介绍的是多路复用机制,也就是同时监听多个套接字连接。
select()的机制中提供一fd_set的数据结构,实际上是一long类型的数组,
每一个数组元素都能与一打开的文件句柄(不管是Socket句柄,还是其他
文件或命名管道或设备句柄)建立联系,建立联系的工作由程序员完成,
当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执
行了select()的进程哪一Socket或文件可读。
有时,select()也被用来当作延时函数使用。sleep()延时会释放cpu,用select的话,可以在占用cpu的情况下,延时
int select(
int nfds,
fd_set* readfds,
fd_set* writefds,
fd_set* exceptfds,
const struct timeval* timeout
);
参数:
nfds
需要检查的文件描述字个数(即检查到fd_set 的第几位),数值应该比三组fd_set中所含的最大fd值更大,一般设为三组fd_set中所含的最大fd值加1(如在readset, writeset,exceptset中所含最大的fd为5,则nfds=6,因为fd是从0开始的)。设这个值是为提高效率,使函数不必检查 fd_set的所有1024位。
readset
用来检查可读性的一组文件描述字。
writeset
用来检查可写性的一组文件描述字。
exceptset
用来检查是否有异常条件出现的文件描述字。(注:错误不包括在异常条件之内)
timeout
有三种可能:
1. timeout="NULL"(阻塞:直到有一个fd位被置为1函数才返回)
2. timeout所指向的结构设为非零时间(等待固定时间:有一个fd位被置为1或者时间耗尽,函数均返回)
3. timeout所指向的结构,时间设为0(非阻塞:函数检查完每个fd后立即返回)
select函数作用:在timeout时间内,不断测试不超过nfds 的所有fd,对于每一个接受到外部事件的fd, 将其在fd_set中的位置置1, 其余的没有接收到外部条件的fd位置置0,通外接下来的FD_ISSET进行测试,找到满足条件的所有fd。所以每次在调用select函数之前,要重新对fd_set进行赋值。
select函数返回值:
如果在timeout时间内,有fd满足条件,返回对应位仍然为1的fd的总数。
如果timeout时间用完了,也没有fd接收到外部事件,则返回0
出错的情况返回负数。
四个宏来操作: 完全一点 从accept开始.
fd_set set;
FD_ZERO(&set); /* 将set清零使集合中不含任何fd*/
FD_SET(fd, &set); /* 将fd加入set集合 */
FD_CLR(fd, &set); /* 将fd从set集合中清除 */
FD_ISSET(fd, &set); /* 测试fd是否在set集合中*/
过去,一个fd_set通常只能包含<32的fd(文件描述 字),因为fd_set其实只用了一个32位矢量来表示fd;现在,UNIX系统通常会在头文件中定义常量 FD_SETSIZE,它是数据类型fd_set的描述字数量,其值通常是1024,这样就能表示<1024的fd。根据fd_set的位矢量实 现,我们可以重新理解操作fd_set的四个宏:
fd_set set;
FD_ZERO(&set); /*将set的所有位置0,如set在内存中占8位则将set置为
00000000*/
FD_SET(0, &set); /* 将set的第0位置1,如set原来是00000000,则现在变为10000000,这样fd==1的文件描述字就被加进set中了 */
FD_CLR(4, &set); /*将set的第4位置0,如set原来是10001000,则现在变为10000000,这样fd==4的文件描述字就被从set中清除了 */
FD_ISSET(5, &set); /* 测试set的第5位是否为1,如果set原来是10000100,则返回非零,表明fd==5的文件描述字在set中;否则返回0*/
- unix 网络编程 select 讲解
- UNIX网络编程--I/O复用:select函数和poll函数讲解(六)
- UNIX网络编程--I/O复用:select函数和poll函数讲解(六)
- UNIX网络编程:select,epoll,poll比较
- Unix网络编程select、poll、epoll比较
- 《unix网络编程》(13)select、shutdown函数
- UNIX网络编程3 使用select()
- UNIX网络编程:select,epoll,poll比较
- UNIX网络编程:select,epoll,poll比较
- unix 网络编程---select回射TCP,UDP
- unix网络编程之利用select 实现群发的功能
- unix 网络编程--select (一)
- Linux/Unix IO多路复用之select网络编程(含源码)
- Linux/Unix网络编程 epoll和select/poll的对比
- Linux/Unix IO多路复用之select网络编程(含源码)
- Unix 网络编程 select 与 epool 函数的区别
- UNIX网络编程2 理解select、poll、epoll原理
- unix网络编程 select函数和shutdown函数
- 进程终止
- svn配置
- JS:jquery插件表格单元格合并.
- dom4j解析xml文件
- 修改MFC窗口标题和图标
- unix 网络编程 select 讲解
- HALCON 算子函数(七) Image
- pendingintent重复问题
- socket阻塞与非阻塞,同步与异步、I/O模型
- node.js addons development Prerequisite knowledgement/node.js插件开发预备知识
- .NET框架
- 编译Ant时JUnit的问题
- "我分你享-家庭版"iPhone手机应用介绍
- 计算累计电费回收率,的存储过程。2013-7-9