1.2 socket编程
socket编程在通信系统设计中有很重要的地位,Jabberd服务器也是如此。因此在度Jabberd源码过程中要了解socket编程的知识。
1.2.1 select函数
为了实现单线程驱动,必须借助系统函数select或poll。select或poll可同时侦听多个socket上的事件,当某个socket上有事件发生时select函数就会返回,这时就可以对这个事件处理。这样就把一个同步阻塞的操作变成了异步操作,使单线程的事件驱动成为可能。
下面首先介绍select函数。
select()函数
文件包含 #include <sys/select.h>
a. 函数原型
int select(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
参数说明:
maxfds 最大句柄数加1
fd_set *readfds 监视的可读文件句柄集合
fd_set *writefds 监视的可写文件句柄集合
fd_set *exceptfds 监视的异常文件句柄集合
timeout 本次select()的超时结束时间。它告诉内核等待任一句柄准备好,允许花费的时间。这里会有三种情况,
第一种情况是timeout是NULL,这样将一直等待,直到某个描述符准备好;
第二种情况是timeout的值是0,那么将不等待,立即返回;
第三种情况是timeout中的秒或微秒被赋值,那么将等待指定的时间。
此外,如果进程收到一个信号,select也会被中断返回。
返回值:
如果函数超时,未发现有套接字活动的,返回0;
函数执行错误,返回-1;
如果有套接字活动,返回套接字的数量。
b. fd_set说明
fd_set是一个整数数组,每个数中的每一位对应一个描述符。例如用32位表示一个整数,那么数组的第一个元素对应于描述字0~31,第二个元素对应于描述字32~63。
注:win32和linux的socket结构不同。win32是句柄形式,socket的值相对很大;而linux上的fd是文件描述符,它的值很小,fd本身就可以做为数组的下标。win32的socket的值不适合做数组的下标,因此在在windows版代码中的mio_fd_t中引入了index变量,用来记录该socket在数组fds中的位置。