select io 多路复用
来源:互联网 发布:linux极点五笔输入法 编辑:程序博客网 时间:2024/05/16 23:43
select主要用于检测多个fd状态,可检测fd大小收内核编译宏__FD_SETSIZE限制,默认为1024。
当打开的fd较多时,select的效率会降低。可修改下面简单服务器模型为仅接受连接,当fd数量超过20000时,select返回明显变慢。
1.简单单线程同时处理多连接的服务器模型
void testSelectSocket(){int nListenFd; int nLen; struct sockaddr_in ServerAddress,ClientAddress; int result; fd_set readfds, testfds; nListenFd = socket(AF_INET, SOCK_STREAM, 0);ServerAddress.sin_family = AF_INET; ServerAddress.sin_addr.s_addr = htonl(INADDR_ANY); ServerAddress.sin_port = htons(1234); nLen = sizeof(ServerAddress); bind(nListenFd, (struct sockaddr *)&ServerAddress, nLen); listen(nListenFd, 5);printf("listen %d\r\n",nListenFd);fd_set readFds;std::set<int> ClientFds;while(1){FD_ZERO(&readFds);FD_SET(nListenFd,&readFds);std::set<int>::const_iterator it(ClientFds.begin()),itEnd(ClientFds.end());for(;it != itEnd;++it)FD_SET(*it,&readFds);int nRet = select(FD_SETSIZE,&readFds,NULL,NULL,NULL);if(nRet == -1){printf("select error.");return;}else if(nRet > 0){for(int fd=0;fd != FD_SETSIZE;++fd){if(FD_ISSET(fd,&readFds)){if(fd == nListenFd){socklen_t nLen = sizeof(ClientAddress); int client_sockfd = accept(nListenFd, (struct sockaddr *)&ClientAddress, &nLen);printf("accept %d,\r\n",client_sockfd); ClientFds.insert(client_sockfd);}else{printf("%d has thing.\r\n",fd);int nRead;//test if there some data to read;ioctl(fd, FIONREAD, &nRead);char ch; if(nRead != 0)nRead = read(fd, &ch, 1); if(nRead == 0) { close(fd); //FD_CLR(fd, &readFds); ClientFds.erase(fd);printf("removing client on fd %d\r\n", fd); } else{if(ch != '\r' && ch != '\n')printf("serving client on fd %d %c %d \r\n", fd,ch,ch); } }}}}else{printf("select time out");return;}}}
2.实现对fd的time read
int Read(int fd, char * pBuffer, unsigned int nBufferLend, unsigned int nMillisecondTimeOut){struct timeval TimeOut;TimeOut.tv_sec = nMillisecondTimeOut / 1000;TimeOut.tv_usec = (nMillisecondTimeOut%1000)*1000;int nReadLen = 0;char* ptr = pBuffer;fd_set readFds;FD_ZERO(&readFds);FD_SET(fd,&readFds);while(nReadLen < nBufferLend){int nRet = select(fd+1,&readFds,NULL,NULL,&TimeOut);if(nRet == -1){nReadLen = -1;perror("select error");break;}else if(nRet > 0){nRet = read(fd,ptr,1);printf("remain time,sec: %d,usec: %d\n",TimeOut.tv_sec,TimeOut.tv_usec);if(nRet < 0){perror("read err:");break;}else if(nRet == 0)break;nReadLen += nRet;ptr += nRet;}else{nReadLen = -1;printf("timeout!\n");break;}}return nReadLen;}
0 0
- IO多路复用--select
- select io 多路复用
- IO多路复用之select
- IO多路复用select
- IO多路复用学习select
- IO多路复用 Select模型
- IO多路复用之select
- IO多路复用-Select
- IO多路复用 - select
- select-IO多路复用
- IO多路复用之select
- io多路复用 select
- IO多路复用select函数
- select-IO多路复用
- 多路复用IO&select&poll
- IO多路复用之select
- IO多路复用-select()
- IO多路复用之select
- 30岁之前如何投资自己?
- PHP字符串的递增和递减示例代码
- 2014年 游戏行业上市与退市都是潮流
- skip list跳表C语言代码。
- VC6.0 下设置控件字体大小
- select io 多路复用
- eclipse常用快捷键
- javascript深入理解js闭包
- PHP特殊字符前加斜杠示例代码
- pat 1006
- ORACLE数据库SQL优化--->基于成本的优化器
- 使用MediaRecorder录制音视频
- SpringMVC视图解析器
- Integer.valueOf(String) 方法之惑