poll服务器编程综合
来源:互联网 发布:王安石 张居正 知乎 编辑:程序博客网 时间:2024/06/05 02:55
一、poll服务器代码
#include<stdio.h>#include <sys/types.h> /* See NOTES */#include <sys/socket.h>#include<stdlib.h>#include<netinet/in.h>#include<poll.h>#include<string.h>static void usage(const char *str){ printf("Usage:%s [serv_ip] [serv_port]\n",str);}static int startup(const char *ip,int port){ int sock = socket(AF_INET,SOCK_STREAM,0); if(sock < 0) { perror("socket"); exit(1); } int opt = 1; setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); struct sockaddr_in serv_addr; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(ip); serv_addr.sin_port = htons(port); int ret = bind(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)); if(ret < 0) { perror("bind"); exit(2); } ret = listen(sock,128); if(ret < 0) { perror("listen"); exit(3); } return sock;}// poll函数第一个参数类型。//struct pollfd {// int fd; /* file descriptor */// short events; /* requested events */// short revents; /* returned events *///};//int main(int argc ,char *argv[]){ if(argc != 3) { usage(argv[0]); return 1; } int sock = startup(argv[1],atoi(argv[2]) ); struct pollfd peerfd[1024]; //当有就绪事件发生的话会写到这个数组里面。 peerfd[0].fd = sock; //首先监听连接套接字。监听它的读事件。 peerfd[0].events = POLLIN; int timeout = -1; //表示阻塞式等待。 int i = 1; for(; i < 1024; ++i) { peerfd[i].fd = -1; //表示这个位置么有被占用。 } while(1) { //int poll(struct pollfd *fds, nfds_t nfds, int timeout); //timeout是一个值传递,不用每次都初始化了。 int ret = 0; switch(ret = poll(peerfd,1024,timeout)) { case 0: printf("timeout...\n"); break; case -1: perror("poll"); break; default: { int i = 0; for(i = 0; i < 1024; ++i)//遍历数组查看有哪些就绪事件发生了。 { if(i == 0 && (peerfd[i].revents & POLLIN) )//有新的连接请求。 { struct sockaddr_in client; socklen_t len = sizeof(client); int new_sock = accept(sock,(struct sockaddr*)&client,&len); if(new_sock < 0) { perror("accept"); continue; } printf("get a new client\n"); int j = 1; for(; j < 1024; ++j) { if(peerfd[j].fd < 0) //找最小的未被使用的位置。 { peerfd[j].fd = new_sock; peerfd[j].events = POLLIN; break; } } if(j == 1024 ) { printf("too many client...\n"); close(new_sock); } } //if else if(i != 0) { if(peerfd[i].revents & POLLIN) //客户端有读事件发生。 { char buf[1024]; ssize_t s = read(peerfd[i].fd,buf,sizeof(buf) - 1); if(s > 0) { buf[s] = 0; printf("clinet say:%s\n",buf); peerfd[i].events = POLLOUT; //读完后监听写事件。 } else if(s <= 0) { close(peerfd[i].fd); peerfd[i].fd = -1; } } else if(peerfd[i].revents & POLLOUT)//写事件就绪。 { /* 客户端写事件发生 */ /* 使用浏览器测试,写回到客户端,浏览器会解析字符串,显示 Hellp Epoll! */ const char* msg = "HTTP/1.1 200 OK\r\n\r\n<html><br/><h1>Hello poll!</h1></html>"; write(peerfd[i].fd, msg, strlen(msg)); //写完后关闭套接字。 close(peerfd[i].fd); peerfd[i].fd = -1; } } //else if } //for } //default } //switch() } //while(1) return 0;}
二、poll服务器优缺点
优点
(1)poll() 不要求开发者计算最大文件描述符加一的大小。 (2)poll() 在应付大数目的文件描述符的时候相比于select速度更快 (3)它没有最大连接数的限制,原因是它是基于链表来存储的。
缺点
(1)大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。 (2)与select一样,poll返回后,需要轮询pollfd来获取就绪的描述符
阅读全文
0 0
- poll服务器编程综合
- e-poll服务器编程综合
- select服务器编程综合
- Linux网络编程/poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- 《unix网络编程》(15)poll函数以及使用poll的客户服务器程序
- 《Linux网络编程》综合案例web服务器shttpd
- poll f服务器
- poll服务器与客户端
- Linux poll服务器
- TensorFlow学习--卷积神经网络CNN
- Principal Component Analysis,PCA主成分分析
- 很开心
- TypeScript 学习笔记2: Getting Started
- Keil连接生成bin文件时报错:--- Error: User Command terminated, Exit-Code = 1
- poll服务器编程综合
- 普通的APK安装更新
- ES6
- 不需要导入外部包,自行编写的json字符串转map工具类
- Java最简单的UDP收发数据的例子
- 学习JVM
- 实战
- Windows下使用dev-cpp连接mysql数据库
- 一大波Android技术干货