套接字Select I/O模型
2011-09-23 17:56
141 查看
select模型 select(选择)模型是winsock中常见的I/O模型。之所以称其为“select模型”,是由于它的 “中心思想”是利用select函数,实现对I/O的管理!最初设计该模型时,主要面向的是某些使用 Unix操作系统的计算机,它们采用的是Berkeley套接字方案。select模型已经集成到Winsock1.1中。 1 .通过调用select函数可以确定一个或多个套接字的状态,判断套接字上是否有数据,或 者能否向一个套接字写入数据。 int select (int nfds, //忽略 fd_set FAR *readfds, //等待可读性检查的套接字组的地址 fd_set FAR *writefds, //等待可写性检查的套接字组的地址 fd_set FAR *exceptfds, //等待错误检查的套接字组的地址 const struct timeval FAR *timeout); //struct timeval结构体地址,select() 最多等待的时间 //返回值 0--超时,SOCKET_ERROR--失败 //说明:此函数的作用是删除fd_set结构体中没有IO操作的套接字 2.管理套接字的结构体 定义: typedef struct fd_set { u_int fd_count; //元素的个数 SOCKET fd_array[FD_SETSIZE]; } fd_set; 对struct fd_set结构体操作的宏 FD_SETSIZE 容量,指定fd_array数组大小,默认为64,也可自己修改宏 FD_ZERO(*set) 置空,使数组的元素值都为3435973836,元素个数为0. FD_SET(s, *set) 添加,向 struct fd_set结构体添加套接字s FD_ISSET(s, *set) 判断,判断s是否为 struct fd_set结构体中的一员 FD_CLR(s, *set) 删除,从 struct fd_set结构体中删除成员s 3.用Select模型获取网络事件 FD_SET AllSockFd; //装有所有的套接字 FD_ZERO(&AllSockFd); AllSockFd = ClientSockFd ; FD_SET(ListenSock, &AllSockFd); FD_SET ReadSockFd; //读集合 FD_SET WriteSockFd; //写集合 while(1) { FD_ZERO(&ReadSockFd); FD_ZERO(&WriteSockFd); ReadSockFd = AllSockFd; WriteSockFd = AllSockFd; int nRet = select(0, &ReadSockFd, &WriteSockFd, NULL, NULL); if(SOCKET_ERROR == nRet) { continue; } //有请求事件发生 if (FD_ISSET(ListenSock, &ReadSockFd)) { //接受请求 SOCKET ClientSock; u_short Port; bool nRe = (*(Pam.pListenSock)).Accept(&ClientSock, 0, &Port); if(nRe) { FD_SET(ClientSock, Pam.pClientSockFd); //设置套接字发送缓冲区80K int nBuf = SOCKET_BUFF; int nBufLen = sizeof(nBuf); int nRe = setsockopt(ClientSock, SOL_SOCKET, SO_SNDBUF, (char*)&nBuf, nBufLen); if(SOCKET_ERROR == nRe) AfxMessageBox("setsockopt error!"); //检查缓冲区是否设置成功 nRe = getsockopt(ClientSock, SOL_SOCKET, SO_SNDBUF, (char*)&nBuf, &nBufLen); if(SOCKET_BUFF != nBuf) AfxMessageBox("检查缓冲区:setsockopt error!"); else AfxMessageBox("已连接客户端!"); } } //判断是否可读或可写 for(u_int n = 0;n < ClientSockFd.fd_count;n++) { if(FD_ISSET(ClientSockFd.fd_array , &ReadSockFd)) //发现可读 { //接收数据 //如果失败 删除此元素 } if(FD_ISSET(ClientSockFd.fd_array , &WriteSockFd)) //发现可写 { //发送缓冲区未满可以发送 //如果失败 删除此元素 } } }
相关文章推荐
- 套接字I/O模型之WSAEventSelect
- 套接字IO模型(三) WSAEventSelect模型
- WinSock学习笔记4:WSAEventSelect模型
- WinSock IO模型 -- WSAEventSelect模型事件触发条件说明
- 服务器IO模型之Select
- 几种并发服务器模型的实现:多线程,多进程,select,poll,epoll
- 套接字I/O模型之WSAEventSelect
- 用select改进回射客户-服务器模型
- 基于select模型的udp客户端实现超时机制
- socket编程的select模型
- WinSock学习(1):Select模型
- I/O复用三大模型select/poll/epoll
- select模型的应用
- 网络编程 select模型
- [转载]Windows网络编程系列教程之四:Select模型
- C++ Windows 上简单的非阻塞Select模型
- select 模型 实现并发 demo
- WsaAsyncSelect编程模型
- IO模型及select、poll、epoll和kqueue的区别
- WSAEventSelect模型 用法介绍