linux 下 poll 编程
poll 与 select 很类似,都是对描述符进行遍历,查看是否有描述符就绪。如果有就返回就绪文件描述符的个数将。poll 函数如下:
#include <poll.h>
int poll(struct pollfd *fdarray, unsigned long nfds, int timeout)
第一个参数指向结构数组第一个元素的指针,每个数组都是一个 pollfd 结构,用于指定测试某个给定描述符 fd 的条件。
struct pollfd
{
int fd;
short events;//关心 fd 上发生的事件
short revents;//fd 实际上上发生的事件
}
要测试的条件由 events 成员指定,函数在相应的 revents 成员中返回该描述符的状态(每个描述符都有两个变量,一个为调用值,另一个为返回结果,从而避免值-结果参数)这两个成员中的每一个都由指定某个特定条件的一位或多位组合而成。下标列出指定 events 标志以及测试 revents 标志的一些常值。
----------------------------+---------------------------------------+---------------------------------------+----------------------------------------+
常量 | 能做为 events 的输入吗? | 能作为revents 的结果吗? | 说明 |
----------------------------+---------------------------------------+---------------------------------------+----------------------------------------+
POLLIN | 能 | 能 | 普通或者优先级带数据可读 |
POLLRDNORM | 能 | 能 | 普通数据可读 |
POLLRDBAND | 能 | 能 | 优先级带数据可读 |
POLLPRI | 能 | 能 | 高优先级数据可读 |
----------------------------+---------------------------------------+---------------------------------------+----------------------------------------+
POLLOUT | 能 | 能 | 普通数据可写 |
POLLWRNORM | 能 | 能 | 普通数据可写 |
POLLWRBAND | 能 | 能 | 优先级带数据可写 |
----------------------------+---------------------------------------+--------------------------------------+-----------------------------------------+
POLLERR | | 能 | 发生错误 |
POLLHUP | | 能 | 发生挂起 |
POLLNVAL | | 能 | 描述字不是一个打开的文件 |
-----------------------------+--------------------------------------+---------------------------------------+----------------------------------------+
第二个参数 nfds 制定数组中元素个数。第三个参数指定 poll 函数返回前等待多长时间。 INFTIM 表示永远等待, 0 代表立即返回, > 0 等待指定数目的秒数。
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <stdio.h>
- #include <error.h>
- #include <errno.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/wait.h>
- #include <limits.h>
- #include <poll.h>
- #include <sys/stropts.h>
- #include <signal.h>
- #define MAXLINE 5
- #define OPEN_MAX 1024
- #define SA struct sockaddr
- int main()
- {
- int listenfd, connfd, sockfd, i, maxi;
- int nready;
- socklen_t clilen;
- ssize_t n;
- char buf[MAXLINE];
- struct pollfd client[OPEN_MAX];
- struct sockaddr_in servaddr, cliaddr;
- //创建监听套接字
- if((listenfd = socket(AF_INET, SOCK_STREAM, )) < )
- {
- printf("socket() error!");
- exit();
- }
- //先要对协议地址进行清零
- bzero(&servaddr,sizeof(servaddr));
- //设置为 IPv4 or IPv6
- servaddr.sin_family = AF_INET;
- //绑定本地端口号
- servaddr.sin_port = htons();
- //任何一个 IP 地址,让内核自行选择
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- //绑定套接口到本地协议地址
- if(bind(listenfd, (SA *) &servaddr,sizeof(servaddr)) < )
- {
- printf("bind() error!");
- exit();
- }
- //服务器开始监听
- if(listen(listenfd,) < )
- {
- printf("listen() error!");
- exit();
- }
- client[].fd = listenfd;
- client[].events = POLLRDNORM;//关心监听套机字的读事件
- for(i = ; i < OPEN_MAX; ++i)
- {
- client[i].fd = -;
- }
- maxi = ;
- for(;;)
- {
- nready = poll(client, maxi + , -);
- if(client[].revents & POLLRDNORM)
- {
- clilen = sizeof(cliaddr);
- //accept 的后面两个参数都是值-结果参数,他们的保留的远程连接电脑的信息,如果不管新远程连接电脑的信息,可以将这两个参数设置为 NULL
- connfd = accept(listenfd, (SA *) &cliaddr, &clilen);
- if(connfd < )
- {
- continue;
- }
- for(i = ; i < OPEN_MAX; ++i)
- {
- if(client[i].fd < )
- client[i].fd = connfd;
- break;
- }
- if(i == OPEN_MAX)
- {
- printf("too many clients");
- exit();
- }
- client[i].events = POLLRDNORM;
- if(i > maxi)
- {
- maxi = i;
- }
- if(--nready <= )
- continue;
- }
- for(i = ; i < OPEN_MAX; ++i)
- {
- if((sockfd = client[i].fd) < )
- {
- continue;
- }
- if(client[i].revents & POLLRDNORM | POLLERR)
- {
- if((n = read(sockfd, buf, MAXLINE)) < )
- {
- if(errno == ECONNRESET)
- {
- close(sockfd);
- client[i].fd = -;
- }
- else
- {
- printf("read error!\n");
- }
- }
- else if(n == )
- {
- close(sockfd);
- client[i].fd = -;
- }
- else
- {
- write(sockfd, buf, n);
- }
- if(--nready <= )
- break;
- }
- }
- }
- }
配合 linux 下 select 编程 就是一个完整的客户端/服务器端代码了,运行结果截图如下:
客户端:
服务器端:
linux 下 poll 编程的更多相关文章
- Linux 下IOport编程訪问
曾经写的一篇笔记.偶尔翻出来了,放在这里做个纪念 Linux 下IOport编程訪问 这里记录的方法是在用户态訪问IOport,不涉及驱动程序的编写. 首先要包括头文件 /usr/include/as ...
- Linux下Socket编程的端口问题( Bind error: Address already in use )
Linux下Socket编程的端口问题( Bind error: Address already in use ) 在进行linux网络编程时,每次修改了源代码并再次编译运行时,常遇到下面的地使用错误 ...
- linux下socket编程实例
linux下socket编程实例一.基本socket函数Linux系统是通过提供套接字(socket)来进行网络编程的.网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符.s ...
- Linux 下shell 编程学习脚手架
linux body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-t ...
- linux下libnet编程 亲自测试可用
linux下libnet编程 亲自测试可用 亲自测试 如果build包的时候 只要把类型改了 就能改成相应的协议. 0x0800 ip 0x0806 arp 0x86DD IPv6 0x86e ...
- Linux下socket编程基本知识
本文档主要讲解了Linux下socket编程的一些基本知识,主要包括套接字和字节序的概念,以及一些常用的结构体和函数. 本文是在网易云课堂学习过程中的记录,这个老师讲得很不错,推荐大家围观. Linu ...
- linux 下 epoll 编程
转载自 Linux epoll模型 ,这篇文章讲的非常详细! 定义: epoll是Linux内核为处理大批句柄而作改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显 ...
- linux 下 select 编程
linux 下的 select 知识点 unp 的第六章已经描述的很清楚,我们这里简单的说下 select 的作用,并给出 select 的客户端实例.我们知道 select 是IO 多路复用的一个最 ...
- linux下socket编程
相关结构 //下边这两个结构定义在<sys/types.h>里 //一般的地址结构,只能用于覆盖(把其他地址转换为此类型),且只能引用该地址的sa_family字段 struct sock ...
随机推荐
- jasper2
package jasper; import java.io.File;import java.io.FileOutputStream;import java.io.OutputStream;impo ...
- thinkphp之wampserver安装
1.如何修改www目录 打开httpd.conf(wamp\bin\apache\Apache2.4.4\conf): 把DocumentRoot "c:/wamp/www" 修改 ...
- Library cache lock 故障解决一例
今天收到同事电话,说是数据库中一张名为acct_balance进行操作是奇慢,第一反映是不是扫行计划有问题,结果我错了,现将过程记录下来. 用pl/sql连上数据库情况:1.对acct_balance ...
- 菜鸟笔记之java中方法使用
N!!!java中无参无返回值方法的使用 1,定义方法 eg: public void show(){ System.out.println("HelloWorld!") } -- ...
- 10.13_extjs,combox,效率为什么这么低
(1)今天很累!经过三天的奋斗,终于完成了完全最优界面的快捷选址功能.今天是最后一天,最紧张,也最累. 为何我的效率不高呢?!我的时间都花费到哪儿呢?①阅读代码理解过去的逻辑:②关键技术上的再复习再巩 ...
- windows phone 8 设置锁屏背景
本来想研究一下 利用闪光灯实现手电筒的代码,发现不是简答设置FlashMode属性可以解决问题的,ms也没有提供api,无意瞄了一眼侧边栏的文章列表,发现了设置屏幕锁屏背景的实现,手一抖点进去了.还算 ...
- 网站开发常用jQuery插件总结(六)关键词说明插件cluetip
我们开发的网站,总有它一定的用途.如企业站用来宣传企业或展示产品,技术站用来分享自己的思路和经验.既然网站有了它的用途,那么就拥有了它本身的关键词(关键词说明网站的主要内容).例如企业站的关键词大部分 ...
- linux扩展lvm磁盘
env: centos 6.5 x64 hyper-v虚拟机 这个方法可以在当前运行的系统中扩展root磁盘 详细步骤 之前想创建的一个虚拟机的磁盘空间不够用了,所以想扩容一下磁盘. 正好使用的时候是 ...
- JavaScript入门介绍(二)
JavaScript入门介绍 [函数] 函数function 是Javascript的基础模块单元,用于代码的复用.信息影藏和组合调用. function a(){} 函数对象Function Lit ...
- mongodb3.2系统性学习——5、游标 模糊查询 findAndModify函数
1首先介绍查询结果 返回的过程: 进行查询的时候mongodb 并不是一次哪个返回结果集合的所有文档,而是以多条文档的形式分批返回查询的结果,返回文档到内存中. 好处: 减少了客户端与服务器端的查询负 ...