select (Unix)
来源:互联网 发布:e4a怎么写入数据库 编辑:程序博客网 时间:2024/05/21 22:30
select是用于I/O多路转接的一个系统调用函数。在C程序中,它定义于sys/select.h或unistd.h。 使用select要使用这些文件和 sys/time.h。
声明:
int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, struct timeval* timeout);
为了维护fd_set类型的参数,会使用下面四个宏:FD_SET(), FD_CLR(), FD_ZERO() 和 FD_ISSET()。
返回值:
这个函数将返回描述符集的个数, 如果超时返回为0,错误则返回-1。
参看:
- select(2)
- poll(2)
目录
- 1select与epoll的区别
- 2示例
- 3参见
- 4外部链接
select与epoll的区别
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;
struct epoll_event { __uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
long tv_sec;//second
long tv_usec;//minisecond
}
typedef struct fd_set
{
u_int fd_count;
int fd_array[FD_SETSIZE];
}
//fd_array可SIZE*8个socket
EPOLLOUT:表示对应的文件描述符可以写;
EPOLLPRI: 表示对应的文件描述符有紧急的数据可读;
EPOLLERR: 表示对应的文件描述符发生错误;
EPOLLHUP:表示对应的文件描述符被挂断;
EPOLLET: ET的epoll工作模式;
readfds, writefds, exceptionfds
四个宏: FD_ZERO FD_SET FD_CLR FD_ISSET运行模式Edge Triggered (ET)、Lev Triggered (LT)LT运行过程int fd = epoll_create(xxA); //xxA可监听的socket
struct epoll_event events[xxxB];//可返回的事件数
while(1){
int nfds = epoll_wait( ); //wait event occur for(int i=0; i<nfds; i++){ …. }//end for
}//end while
fd_set rfds;
tv={5,0}; //set time out
while(1){
FD_ZERO(&rfds); if (!select()) continue; for(int i=0;i<maxfds; i++){ ...} //end for
} //end while
优点1)epoll_wait返回的都是有效数据,可直接从struct epoll_event[]中获取事件,效率高。 缺点 每次select有数据要遍历全部socket注意事项每次取事件后,要重新注册此socket的事件epoll。(epoll_ctl)每次select之前要重置rfds的值。(FD_ZERO)说明:以上无论epoll_create, fd_set都受限于系统中单个进程能够打开的文件句柄数。
示例
#include <stdio.h>#include <stdlib.h>#include <string.h> #include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h> #include <sys/select.h>#include <fcntl.h>#include <unistd.h>#include <errno.h> #define PORT "9421" /* function prototypes */void die(const char*); int main(int argc, char **argv){int sockfd, new, maxfd, on = 1, nready, i; struct addrinfo *res0, *res, hints; char buffer[BUFSIZ]; fd_set master, readfds; ssize_t nbytes; (void)memset(&hints, '\0', sizeof(struct addrinfo)); hints.ai_family = AF_INET;hints.ai_socktype = SOCK_STREAM;hints.ai_protocol = IPPROTO_TCP;hints.ai_flags = AI_PASSIVE; if(-1 == (getaddrinfo(NULL, PORT, &hints, &res0)))die("getaddrinfo()"); for(res = res0; res; res = res->ai_next){if(-1 == (sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol))){perror("socket()");continue;} if(-1 == (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(int)))){perror("setsockopt()");continue;} if(-1 == (bind(sockfd, res->ai_addr, res->ai_addrlen))){perror("bind");continue;} break; } if(-1 == sockfd)exit(EXIT_FAILURE); freeaddrinfo(res0); if(-1 == (listen(sockfd, 32)))die("listen()"); if(-1 == (fcntl(sockfd, F_SETFD, O_NONBLOCK)))die("fcntl()"); FD_ZERO(&master);FD_ZERO(&readfds); FD_SET(sockfd, &master); maxfd = sockfd; while(1){memcpy(&readfds, &master, sizeof(master)); (void)printf("running select()\n"); if(-1 == (nready = select(maxfd+1, &readfds, NULL, NULL, NULL)))die("select()"); (void)printf("Number of ready descriptor: %d\n", nready); for(i=0; i<=maxfd && nready>0; i++){if(FD_ISSET(i, &readfds)){nready--; if(i == sockfd){(void)printf("Trying to accept() new connection(s)\n"); if(-1 == (new = accept(sockfd, NULL, NULL))){if(EWOULDBLOCK != errno)die("accept()"); break;} else{ if(-1 == (fcntl(new, F_SETFD, O_NONBLOCK)))die("fcntl()"); FD_SET(new, &master); if(maxfd < new)maxfd = new;}} else{(void)printf("recv() data from one of descriptors(s)\n"); nbytes = recv(i, buffer, sizeof(buffer), 0);if(nbytes <= 0){if(EWOULDBLOCK != errno)die("recv()"); break;} buffer[nbytes] = '\0';printf("%s", buffer); (void)printf("%zi bytes received.\n", nbytes); close(i);FD_CLR(i, &master); }} } } return 0;} void die(const char *msg){perror(msg);exit(EXIT_FAILURE);}
- select (Unix)
- unix select 模型
- Unix select()的使用
- Unix select()的使用
- UNIX select socket 应用
- UNIX中的Select函数
- Unix select()的使用
- Unix--select/epoll
- unix 网络编程 select 讲解
- Unix中的select与epoll
- Unix环境高级I/O(Select)
- unix下的多路复用(select)
- UNIX下的select详细说明
- UNIX网络编程:select,epoll,poll比较
- unix高级编程-多路IO select
- Unix网络编程select、poll、epoll比较
- 浅析UNIX中的select和epoll
- 《unix网络编程》(13)select、shutdown函数
- mac android jdk环境配置
- Codeforces Round #301 (Div. 2)C - Ice Cave-bfs
- (素材源码)猫猫学iOS(四十一)UI之核心动画 两行代码搞定3D转场(做android的哭死)
- POJ2243 Knight Moves
- setuid setgid root 权限提升 android root su
- select (Unix)
- 无论你说什么,都有人不能或不愿领会
- eclipse移动上下行
- Codeforces Round #301 (Div. 2)A B C
- epoll
- PHP实现页面静态化--imooc课程
- Spring HttpHeader HttpResponse
- 在gradle中配置apk的签名文件keystore
- 使用POI导出Excel