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( ...
随机推荐
- Window ferformance toolkit 学习
1.环境配置 2.内存泄露 a. 编写自己的wprp文件: http://msdn.microsoft.com/en-us/library/hh448223.aspx b.启动 @echo off s ...
- python知识点杂记2
1. 如果已经有一个list或者tuple,要调用一个可变参数怎么办?2. >>> nums = [1, 2, 3]3. >>> calc(*nums)4. 14* ...
- 转:JDK动态代理为什么必须用接口以及与CGLIB的对比
参考链接: JDK动态代理为什么必须用接口以及与CGLIB的对比 文章中提到:试验了JDK动态代理与CGLIB动态代理.从Spring的AOP框架介绍中得知对于使用接口的类,Spring使用JDK动态 ...
- disruptor的并行用法
实现EventFactory,在newInstance方法中返回,ringBuffer缓冲区中的对象实例:代码如下: public class DTaskFactory implements Even ...
- js中属性类型:数据属性与访问器属性
js中属性类型分为两种:数据属性和访问器属性 在js中,对象都是由名值对构成的,名:就是我们所说的属性名,值就是属性对应的值(基本值.对象.方法). ECMA-262第5版定义了只有内部才用的特性,描 ...
- python解析VOC的xml文件并转成自己需要的txt格式
在进行神经网络训练的时候,自己标注的数据集往往会有数据量不够大以及代表性不强等问题,因此我们会采用开源数据集作为训练,开源数据集往往具有特定的格式,如果我们想将开源数据集为我们所用的话,就需要对其格式 ...
- HttpUrlConneciton上传JSON数据
try { //创建连接 URL url = new URL(url); HttpURLConnection connection = (HttpURLConnection) url.openConn ...
- mysql explain中的 “Select tables optimized away”
mysql explain中的 “Select tables optimized away” http://blog.chinaunix.net/uid-10449864-id-2956845.htm ...
- MHA配置参数详解 【转】
mha配置参数详解: 参数名字 是否必须 参数作用域 默认值 示例 hostname Yes Local Only - hostname=mysql_server1, hostname=192.168 ...
- sed 操作命令
sed介绍 grep 只能过滤文件内容,sed既能过滤文件内容同时还能对文件内容进行修改. sed 算是一种编程语言,它有自己的固定语法. sed是一种行编辑器,sed会在内存中开辟一块独立的空间( ...