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_SETFD_CLRFD_ISSETFD_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集合中,不在则返回0
FD_ZERO(fd_set *fdset);              //将set清零使集合中不含任何fd

posted on 2019-12-01 03:15  lydstory  阅读(513)  评论(0)    收藏  举报

导航