基于select模型的udp客户端实现超时机制
2014-02-18 21:07
489 查看
多路选择I/O — select模型
其思想在于使用一个集合,该集合中包含需要进行读写的fd,通过轮询这个集合,直到有一个fd可读写,才返回。与阻塞I/O不同的是,阻塞I/O仅使用了一次系统调用,就是对fd的读写,如果没有fd处于就绪状态,则进程一直阻塞,而多路选择I/O使用了两次系统调用,第一次是轮询并返回可读写fd数,第二次是对fd进行读写,阻塞只发生在轮询fd的过程。
select函数的原型(sys/select.h)
(1)__nfds
需轮询的最大文件描述符数。如__nfds = 10,则轮询值为0~9的fd,单个进程中,最多可打开1024个fd,该值在sys/select.h中的FD_SETSIZE定义。用户可通过“ulimit -n”查看该值,通过打印/proc/sys/fs/file-max中的值查看系统可打开的最大fd数。
(2)__readfds,__writefds,__exceptfds
分别代表用户关心的可读、可写、异常的fd,这三个参数的数据类型是fd_set *,这是一组文件描述符的集合,使用一个位来代表一个fd。
fd_set位向量操作函数包括
(3)__timeout
timeout的数据类型是timeval结构体。通过填充该结构体,设置超时时间,精确到微妙级,如果该参数设置为NULL,则一直等待,直到有fd可读写。如果tv_sec和tv_usec都设置为0,则轮询完指定fd后,立即返回。
(4)select有三种返回值
-1 :出错
0 :如果设置了超时,在指定时间内没有fd可读写,则返回0,可在此指定相应的超时处理操作。
>0 :返回可读写的fd数
可屏蔽信号的select — pselect
从原型上看,pselect函数与select函数的区别在于设置超时的结构体不同,以及多了个用于屏蔽信号的参数。如果__sigmask设置为NULL,则与select一样。
(1)timespec结构体的定义如下,它精确到纳秒级。
(2)__sigmask实际上是信号的位向量。数据类型是sigset_t,定义如下
模型示例代码如下:
其思想在于使用一个集合,该集合中包含需要进行读写的fd,通过轮询这个集合,直到有一个fd可读写,才返回。与阻塞I/O不同的是,阻塞I/O仅使用了一次系统调用,就是对fd的读写,如果没有fd处于就绪状态,则进程一直阻塞,而多路选择I/O使用了两次系统调用,第一次是轮询并返回可读写fd数,第二次是对fd进行读写,阻塞只发生在轮询fd的过程。
select函数的原型(sys/select.h)
int select (int __nfds, fd_set *__restrict __readfds, fd_set *__restrict __writefds, fd_set *__restrict __exceptfds, struct timeval *__restrict __timeout);
(1)__nfds
需轮询的最大文件描述符数。如__nfds = 10,则轮询值为0~9的fd,单个进程中,最多可打开1024个fd,该值在sys/select.h中的FD_SETSIZE定义。用户可通过“ulimit -n”查看该值,通过打印/proc/sys/fs/file-max中的值查看系统可打开的最大fd数。
(2)__readfds,__writefds,__exceptfds
分别代表用户关心的可读、可写、异常的fd,这三个参数的数据类型是fd_set *,这是一组文件描述符的集合,使用一个位来代表一个fd。
fd_set位向量操作函数包括
#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp) //将指定的fd置1 #define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp) //将指定的fd清0 #define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp) //测试fd状态,如被置1,返回非0,否则返回0 #define FD_ZERO(fdsetp) __FD_ZERO (fdsetp) //将所有的fd清0
(3)__timeout
timeout的数据类型是timeval结构体。通过填充该结构体,设置超时时间,精确到微妙级,如果该参数设置为NULL,则一直等待,直到有fd可读写。如果tv_sec和tv_usec都设置为0,则轮询完指定fd后,立即返回。
struct timeval { __time_t tv_sec; /* Seconds. */ __suseconds_t tv_usec; /* Microseconds. */ };
(4)select有三种返回值
-1 :出错
0 :如果设置了超时,在指定时间内没有fd可读写,则返回0,可在此指定相应的超时处理操作。
>0 :返回可读写的fd数
可屏蔽信号的select — pselect
从原型上看,pselect函数与select函数的区别在于设置超时的结构体不同,以及多了个用于屏蔽信号的参数。如果__sigmask设置为NULL,则与select一样。
int pselect (int __nfds, fd_set *__restrict __readfds, fd_set *__restrict __writefds, fd_set *__restrict __exceptfds, const struct timespec *__restrict __timeout, const __sigset_t *__restrict __sigmask);
(1)timespec结构体的定义如下,它精确到纳秒级。
struct timespec { __time_t tv_sec; /* Seconds. */ long int tv_nsec; /* Nanoseconds. */ };
(2)__sigmask实际上是信号的位向量。数据类型是sigset_t,定义如下
/* A `sigset_t' has a bit for each signal. */ # define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) typedef struct { unsigned long int __val[_SIGSET_NWORDS]; } __sigset_t;
模型示例代码如下:
int maxfdp,sockfd; fd_set fds; struct timeval timeout; int interval = 3; while (1) { timeout.tv_usec = 0; timeout.tv_sec = interval; FD_ZERO(&fds); FD_SET(sockfd, &fds); maxfdp = sockfd + 1; sendto(); switch(select(maxfdp, &fds, NULL, NULL, &timeout)) { case -1: exit(-1); break; case 0: break; default: if(FD_ISSET(fd, &fds)) { revcfrom(); } break; } }
相关文章推荐
- 基于select模型的udp客户端实现超时机制
- 基于select模型的udp客户端实现超时机制
- 基于select模型的udp客户端实现超时机制
- 基于select模型的udp客户端实现超时机制
- 使用Select I/O模型来实现一个并发处理多个客户端的TCP服务器
- 小技巧大作用 《ssh基于客户端认证机制,基于某个用户实现》
- Linux下基于EPOLL 模型,实现用户登录,客户端采用QT
- Java基于UDP实现服务器和多客户端之间的通信
- Python实现基于TCP UDP协议的IPv4 IPv6模式客户端和服务端功能示例
- linux环境下基于UDP的 客户端服务器模型
- iOS —— 客户端Socket UDP协议广播机制的实现
- 基于Netty UDP实现的简单心跳机制
- 通过select模型实现具有超时设定的connect
- 基于WSAEventSelect模型的TCP服务器实现
- 基于UDP 实现客户端之间通信【2】
- VB.NET C#实现基于UDP的免服务器局域网多客户端点对点通讯
- python 3下基于select模型的事件驱动机制程序
- 使用socket实现基于select模型的网络聊天室
- Unix网络编程学习日记(四):基于select的单线程半双工socket客户端的实现
- Select I/O模型来实现一个并发处理多个客户端的TCP服务器