select函数及fd_set介绍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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集合中,不在则返回0 FD_ZERO(fd_set *fdset); //将set清零使集合中不含任何fd |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2017-12-01 g++报错原因分析:expected class-name before ‘{’ token
2017-12-01 lsusb
2017-12-01 mysql的头文件