select函数及fd_set介绍
BOOL CHttpSocket::IsReadible(BOOL& bReadible, DWORD dwTimeout)
{
ASSERT(m_hSocket != INVALID_SOCKET);
timeval timeout;
timeout.tv_sec = dwTimeout / 1000;
timeout.tv_usec = dwTimeout % 1000;
fd_set fds;
FD_ZERO(&fds);
FD_SET(m_hSocket, &fds);
int nStatus = ::select(0, &fds, NULL, NULL, &timeout);
if (nStatus == SOCKET_ERROR)
return FALSE;
else
{
bReadible = !(nStatus == 0);
return TRUE;
}
}
3. 函数定义
该函数声明如下
|
1
|
int select(int nfds, fd_set* readset, fd_set* writeset, fe_set* exceptset, struct timeval* timeout); |
参数:
nfds 需要检查的文件描述字个数
readset 用来检查可读性的一组文件描述字。
writeset 用来检查可写性的一组文件描述字。
exceptset 用来检查是否有异常条件出现的文件描述字。(注:错误不包括在异常条件之内)
timeout 超时,填NULL为阻塞,填0为非阻塞,其他为一段超时时间
返回值:
返回fd的总数,错误时返回SOCKET_ERROR
2. fd_set结构体
上面select函数中需要用到两个fd_set形参,这个结构体到底做什么用的呢
fd_set其实这是一个数组的宏定义,实际上是一long类型的数组,每一个数组元素都能与一打开的文件句柄(socket、文件、管道、设备等)建立联系,建立联系的工作由程序员完成,当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执行了select()的进程哪个句柄可读。
系统提供了FD_SET, FD_CLR, FD_ISSET, FD_ZERO进行操作,声明如下:
|
1
2
3
4
|
FD_SET(int fd, fd_set *fdset); //将fd加入set集合FD_CLR(int fd, fd_set *fdset); //将fd从set集合中清除FD_ISSET(int fd, fd_set *fdset); //检测fd是否在set集合中,不在则返回0FD_ZERO(fd_set *fdset); //将set清零使集合中不含任何fd |
浙公网安备 33010602011771号