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( ...
随机推荐
- 阿里创新自动化测试工具平台--Doom
摘要: 阿里内部诞生一了个依赖真实流量用于自动回归的自动化测试平台,通过创新的自动mock机制不仅支持读接口的回归验证,同时支持了写接口验证,在内部产生了极大价值,有价值的东西就应该分享,目前该工具已 ...
- LeetCode 824 Goat Latin 解题报告
题目要求 A sentence S is given, composed of words separated by spaces. Each word consists of lowercase a ...
- Java之旅_面向对象_重写和重载
参考并摘自:http://www.runoob.com/java/java-override-overload.html 重写(Override) 子类对父类(允许访问的)方法的实现过程进行重新编写, ...
- 洛谷P4495 奇怪的背包 [HAOI2018] 数论
正解:数论+dp 解题报告: 传送门! 首先看到这题,跳无数次,自然而然可以想到之前考过好几次了的一个结论——如果只考虑无限放置i,它可以且仅可以跳到gcd(p,v[i]) 举一反三一下,如果有多个i ...
- wget 下载命令
//下载单个文件 wget http://116.199.2.206:81/2Q2WADC9FB8D469200FF61C643601888142263926D08_unknown_65A3E1A23 ...
- OpenWrt 路由系统上抓包
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/qianguozheng/article/details/32108093 前言: 做路由器开发,难免 ...
- Python3学习之路~4.3 装饰器
定义:本质是函数,装饰其他函数就是为其他函数添加附加功能. 原则: 不能修改被装饰函数的源代码 不能修改被装饰函数的调用方式 实现装饰器知识储备: 函数即“变量” 高阶函数 把一个函数名当做实参传递给 ...
- react 脚手架--create-react-app
1.yarn add -g create-react-app 2.create-react-app demo cd demo yarn start 可以跑起来整个项目了 一般都会用到路由,需要 yar ...
- 万恶之源 - Python迭代器
函数名的使用以及第一类对象 函数名的运用 函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量 1.函数名的内存地址 def func(): print("呵呵" ...
- git flow常用命令
https://danielkummer.github.io/git-flow-cheatsheet/index.zh_CN.html https://blog.csdn.net/shu580231/ ...