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( ...
随机推荐
- 转:Scanner中nextLine()方法和next()方法的区别
原文地址:https://blog.csdn.net/hello_word2/article/details/54895106 总结:next() 读取第一个 空白符之前(不包括空白符)的内容,nex ...
- 图解Fiddler如何抓取Android数据包
介绍Fiddler抓取Android数据包希望对大家的工作和学习有所帮助! 电脑开启wifi热点 首先在电脑上下载一个wifi软件,我这里用的是猎豹wifi,电脑开启wifi热点后,如下图所示: 设 ...
- python摸爬滚打之day01----初识Python
1.编程语言分类 编译型语言:程序被一次性全部翻译成机器语言,计算机直接以机器语⾔言来运⾏行行此程序. 优点:运行效率高,可脱离语言环境独立运行. 缺点:开发效率低,可移植性差. 解释型语言:将程序逐 ...
- Orchard Core 增加了一个API模块,要怎么调用
如下,我在Orchard Core框架中添加了一个API的模块,并且定义了对应的权限才可以调用,那么我们现在考虑的就是要怎么去调用它. 首先,我们用Fiddler查看下我们正常的登录的http报文,直 ...
- 宝塔Linux面板安装Redis
宝塔Linux面板安装Redis不会特别麻烦,只要几步就可以实现:1.安装redis服务2.配置redis设置3.安装PHP扩展,下面就随ytkah一起来看看吧 1.首先,我们来安装redis服务,进 ...
- 关于Go,你可能不注意的7件事
转自: https://tonybai.com/2015/09/17/7-things-you-may-not-pay-attation-to-in-go/ Go以简洁著称,但简洁中不乏值得玩味的小细 ...
- openshift 容器云从入门到崩溃之三《安装openshift》
准备好环境,在安装之前请先了解openshift提供的ansible有大量的安装选项 文档地址:https://docs.okd.io/latest/install/configuring_inven ...
- 一个toolkit或者一个开源项目如何学习它并使用它
一个toolkit或者一个开源项目如何学习它并使用它 一般一个流行的toolkit和开源项目,一般都会被广泛地被应用: 那么,我们如何学习它,如何应用它在自己的业务场景中呢? 答案就是:学习源码并借鉴 ...
- centos上shellcheck的安装
关于shellcheck的作用和功能,自行查阅. centos7 上安装shellcheck的过程中查了很多资料,大部分都是在ubunt下安装的,centos的比较少,然后好不容易看到一个https: ...
- Java Selenium - 处理页面弹出窗
1. 得到当前窗口句柄 2. 得到所有窗口句柄 3. 循环找到目标窗口 String currentWindow = driver.getWindowHandle(); Set<String&g ...