32网络通信之Poll模型
多路复用并发模型 -- poll
#include<poll.h>
int poll(struct pollfd *fds, unsigned int nfds, int timeout);
struct pollfd {
int fd; //轮询的文件描述符
short events; //等待的事件
short revents; //实际发生的事件
}
nfds : fds 数组大小
timeout : 超时时间(毫秒), 0立即返回,负数一直等待
超时返回 0, 出错返回 -1, 正常返回 > 0
多路复用并发模型 -- poll
事件类型
POLLIN 有数据可读
POLLRDNORM 有普通数据可读
POLLRDBAND 有优先数据可读
POLLPRI 有紧迫数据可读
POLLOUT 可以写数据(不会阻塞)
POLLWRNORM 可以写普通数据
POLLWRBAND 可以写优先数据
POLLMSGSIGPOLL 消息可用
POLLER 发生错误 (revents 可用)
POLLHUP 文件描述符挂起 (revents 可用)
POLLNVAL 指定的文件描述符非法(revents可用)
多路复用并发模型 -- poll
用法
POLLIN = POLLRDNORM | POLLBAND
监控可读事件 events = POLLIN | POLLPRI
POLLOUT = POLLWRNORM
监控可写事件 events = POLLOUT | POLLWRBAND
同时监控多个事件 events = XX1 | XX2 | XX3 | ...
若干个事件发生,返回值 revents = XX_N | XX_M | ...
多路复用并发模型 -- poll
poll 模型和 select 本质上差不多,都是fd 轮询
优点:
比之 select,木有最大文件描述符限制
缺点:
和select一样,包含大量文件描述符时,系统开销会很大
#include<stdio.h>
#include<unistd.h>
#include<string.h> #include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h> #include<sys/poll.h>
#include<sys/time.h> #define SRV_PORT 0xabcd
#define CONN_MAX 10000 void PollProcss(struct pollfd *pfds,int *plen)
{
int i;
int fd;
int iRet;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
char szMsg[1000] = { 0 };
char szBuff[1000] = { 0 }; //monitor POLLIN is 1 or 0
if (pfds[0].revents & POLLIN)
{
read(0,szMsg,1000);
for (i = 2; i < *plen; ++i)
{
write(pfds[i].fd, szMsg, strlen(szMsg));
}
}
if (pfds[1].revents & POLLIN)
{
fd = accept(pfds[1].fd, (struct sockaddr*)&addr, &addrlen);
if (fd < 0)
{
perror("Fail to accept!");
return;
}
if (*plen == CONN_MAX)
{
printf("\rConnect over limit\n");
write(fd, "Connect over limit", 20);
close(fd);
}
else
{
write(fd, "Welcome", 8);
printf("\r[%d]New connect from %s[%d]\n", fd, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); pfds[*plen].fd = fd;
pfds[*plen].events = POLLIN; (*plen)++;
}
}
//TranslateMessage DispatchMessage
for (i = 3; i < *plen; ++i)
{
if (pfds[i].fd.revents & POLLIN)
{
memset(szBuff, 0, 1000); iRet = read((pfds[i].fd, szBuff, 1000);
if (iRet < 0)
{
perror("Fail to read!");
break;
}
//Disconnect
else if (iRet == 0)
{
int j;
//Back cover front
for (j = i; j < *plen; ++j)
{
pfds[j].fd = pfds[j + 1].fd;
}
(*plen++);
//
i--; /* That's the same thing as the top
pfds.fd=pfds[*plen-1].fd; //replace pfds[i].fd to last fd
(*plen)--;
i--;
*/ }
//Normal processing data
else
{
printf("\r[%d]Recv:%s\n", pfds[i].fd, szBuff);
} }
} return;
} void PollServer()
{
int fd;
int iRet;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr); fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
perror("Fail to socket!");
return;
} addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(SRV_PORT); iRet = bind(fd, (struct sockaddr*)&addr, addrlen);
if (iRet)
{
perror("Fail to bind!");
close(fd);
return;
} iRet = listen(fd, 100);
if (iRet)
{
perror("Fail to listen!");
close(fd);
return;
} // /////////////init pollfd
//struct pollfd pfds[CONN_MAX];
struct pollfd *pfds = (struct pollfd*)malloc(CONN_MAX *sizeof(struct pollfd));
int nfds = 0; //fd num of array:pfds //monitor stdin
pfds[0].fd = 0;
pfds[0].events = POLLIN;
nfds++; //monitor tcp server fd
pfds[1].fd = fd;
pfds[1].events = POLLIN;
nfds++;
//////////////// printf("Start server ok..\n"); while (1)
{
fprintf(stderr, "Send:");
iRet = poll(pfds, nfds, -1);
if (iRet == 0)
{
//timeout
continue;
}
eles if (iRet < 0)
{
perror("Fail to poll!");
break;
}
else
{
PollProcss(pfds, &nfds);
}
}
close(fd);
return;
} int main()
{
TcpServer(); return 0;
}
32网络通信之Poll模型的更多相关文章
- 网络编程中select模型和poll模型学习(linux)
一.概述 并发的网络编程中不管是阻塞式IO还是非阻塞式IO,都不能很好的解决同时处理多个socket的问题.操作系统提供了复用IO模型:select和poll,帮助我们解决了这个问题.这两个函数都能够 ...
- 多路复用I/O模型poll() 模型 代码实现
多路复用I/O模型poll() 模型 代码实现 poll()机制和select()机制是相似的,都是对多个描述符进行轮询的方式. 不同的是poll()没有描述符数目的限制. 是通过struct pol ...
- 从零开始实现简单 RPC 框架 8:网络通信之 Request-Response 模型
Netty 在服务端与客户端的网络通信中,使用的是异步双向通信(双工)的方式,即客户端和服务端可以相互主动发请求给对方,发消息后不会同步等响应.这样就会有一下问题: 如何识别消息是请求还是响应? 请求 ...
- UNIX网络编程-Poll模型学习
1.相关接口介绍 1.1 poll ---------------------------------------------------------------------- #include &l ...
- 33网络通信之Epoll模型
多路复用并发模型 -- epoll 监控事件 events EPOLLIN fd可读 EPOLLOUT fd可写 EPOLLPRI ...
- 31网络通信之Select模型
多路复用并发模型 -- select #include<sys/select.h> #include<sys/time.h> int select(int maxfd, f ...
- Linux网络通信编程(套接字模型TCP\UDP与IO多路复用模型select\poll\epoll)
Linux下测试代码: http://www.linuxhowtos.org/C_C++/socket.htm TCP模型 //TCPClient.c #include<string.h> ...
- Linux下select, poll和epoll IO模型的详解
http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll 介绍 Epoll 可是当前在 Linux 下开发大规模并发网络程序的热 ...
- select poll epoll Linux高并发网络编程模型
0 发展历程 同步阻塞迭代模型-->多进程并发模型-->多线程并发模型-->select-->poll-->epoll-->... 1 同步阻塞迭代模型 bind( ...
随机推荐
- scrollView截取指定区域的图片
把scrollView放到一个容器里面,再截图就可以了 scrollview放到容器: UIView *lunboCarrier = [[UIView alloc] initWithFrame:CGR ...
- textfield内边距
使用QMUITextField self.inputTf.textInset = UIEdgeInsetsMake(0, -6, 0, 10);
- python摸爬滚打之day12----生成器, 各种生成式
1.生成器 生成器的本质就是迭代器. 1.1 获取生成器 1: 生成器函数 函数中出现 "yield" 的函数就是一个生成器函数, 再次执行函数时就不是运行函数而是获取生成器. ...
- 洛谷P1966 火柴排队 贪心+离散化+逆序对(待补充QAQ
正解: 贪心+离散化+逆序对 解题报告: 链接在这儿呢quq 这题其实主要难在想方法吧我觉得?学长提点了下说用贪心之后就大概明白了,感觉没有很难 但是离散化这里还是挺有趣的,因为并不是能很熟练地掌握离 ...
- 敏捷开发之Scrum扫盲篇(转)
现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后于他人,我也开始学习Scrum.今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的语言来描述Scrum中 ...
- ES6面试题总结
1.说出至少5个ES6的新特性,并简述它们的作用.(简答题) 1.let关键字,用于声明只在块级作用域起作用的变量: 2.const关键字,用于声明一个常量: 3.结构赋值,一种新的变量赋值方式.常用 ...
- 启动Jmeter4.0 后弹出命令窗口提示信息是什么意思?
启动Jmeter4.0 后弹出命令窗口提示信息: =========================================================================== ...
- 数据库---mysql的介绍和安装
MySQL数据库 一.简介: mysql是数据库管理软件:套接字:服务端,客户端 支持并发:操作得是共享得数据 处理锁,数据安全,性能 用别人得软件,得照着别人得规范,组织自己得语法规则 二.概述: ...
- 在WCF服务端的web.config中增加如下设置,具体的错误会记录在.svclog文件中
<system.diagnostics> <sources> <source name="System.ServiceModel" switchVal ...
- FCN-全卷积网络
全卷积网络 Fully Convolutional Networks CNN 与 FCN 通常CNN网络在卷积层之后会接上若干个全连接层, 将卷积层产生的特征图(feature map)映射成一个固定 ...