练习C之SELECT形式的非阻塞IO
2015-11-20 13:39
274 查看
呵呵,理解得不深,但毕竟手打全版,且无错。但select.h不知何处找头文件,
粘下来作个记录。
POLL,EPOLL感觉代码类似,只是函数和系统实现不一样,,EPOLL目前最合理的。定位精确,算法复杂度最好。
粘下来作个记录。
POLL,EPOLL感觉代码类似,只是函数和系统实现不一样,,EPOLL目前最合理的。定位精确,算法复杂度最好。
#include "select.h" #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/select.h> #include <sys/time.h> #include <string.h> #include <netinet/in.h> #include <sys/types.h> typedef struct _CLIENT{ int fd; struct sockaddr_in addr; } CLIENT; #define MYPORT 59000 #define BACKLOG 5 CLIENT client[BACKLOG]; int currentClient = 0; #define REVLEN 10 char recvBuf[REVLEN]; void showClient(); int main() { int i, ret, sinSize; int recvLen = 0; fd_set readfds, writefds; int sockListen, sockSvr, sockMax; struct timeval timeout; struct sockaddr_in server_addr; struct sockaddr_in client_addr; for(i=0; i<BACKLOG; i++) { client[i].fd = -1; } printf("accept started\n"); //socket if ((sockListen = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("socket error\n"); return -1; } bzero(&server_addr, sizeof(server_addr)); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(MYPORT); //bind if(bind(sockListen, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { printf("bind error\n"); return -1; } //listen if(listen(sockListen, 5)< 0) { print("listen error\n"); return -1; } for(i=0; i<BACKLOG; i++) { client[i].fd = -1; } //select while(1) { FD_ZERO(&readfds); FD_SET(sockListen, &readfds); sockMax = sockListen; for(i=0; i<BACKLOG; i++) { if(client[i].fd > 0) { FD_SET(client[i].fd, &readfds); if(sockMax<client[i].fd) { sockMax = client[i].fd; } } } timeout.tv_sec = 3; timeout.tv_usec = 0; ret = select((int)sockMax+1, &readfds, NULL, NULL, &timeout); if(ret < 0) { printf("select error\n"); break; } else if(ret == 0) { printf("timeout...\n"); continue; } printf("test111\n"); for(i=0; i<BACKLOG; i++) { if(client[i].fd>0 && FD_ISSET(client[i].fd, &readfds)) { if(recvLen != REVLEN) { while(1) { ret = recv(client[i].fd, (char *)recvBuf+recvLen, REVLEN-recvLen, 0); if(ret == 0) { client[i].fd = -1; recvLen = 0; break; } else if(ret < 0) { client[i].fd = -1; recvLen = 0; break; } recvLen = recvLen + ret; if(recvLen < REVLEN) { continue; } else { printf("%s, buf = %s\n", inet_nota(client[i].addr.sin_addr), recvBuf); recvLen = 0; break; } } } } } if(FD_ISSET(sockListen, &readfds)) { printf("isset\n"); sockSvr = accept(sockListen, NULL, NULL); if(sockSvr == -1) { printf("accept error\n"); } else { currentClient++; } for(i=0; i< BACKLOG; i++) { if(client[i].fd < 0) { client[i].fd = sockSvr; client[i].addr = client_addr; printf("You got a connection from %s \n", inet_ntoa(client[i].addr.sin_addr)); break; } } } } printf("test\n"); return 0; } void showClient() { int i; printf("client count = %d\n", currentClient); for(i=0; i<BACKLOG; i++) { printf("[%d] = %d", i, client[i].fd); } printf("\n"); }
相关文章推荐
- 高程5.2.9归并方法
- 设置控件的大小比例
- 【三】注入框架RoboGuice使用:(Your First Resource Injection)
- eclipse无法导出android签名包的问题
- jQuery radio的取值与赋值
- HDU 2157 How many ways??
- Win8/8.1系统metro应用中使用IE浏览器出现闪退问题的解决方法
- ACE_Reactor
- HTTP请求报文与响应报文介绍
- http://blog.zhaojie.me/
- Nginx配置文件nginx.conf中文详解
- Python 列表(list)、字典(dict)、字符串(string)常用基本操作小结
- iMindMap如何设置图形样式
- 利用HTML和CSS实现常见的布局
- oracle获取服务器字符集
- 无线客户端同学快速学习ReactNative的学习曲线(转载)
- svn简单使用流程
- 类1调用类2的子方法不会触发类2的main方法
- 第13条:使用类和成员的可访问性最小化
- ACE中对线程的封装