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 ...
随机推荐
- Eclipse中绑定java源代码
如何在Eclipse sdk中查看jar源代码如:*.jar 1.点 “window”-> "Preferences" -> "Java" -&g ...
- Android中使用ViewPager实现广告条
我们在使用电商或视频的手机客户端时,通常会看到广告条的效果.在网上搜索时才知道使用的是ViewPager,于是自己也做了一个Demo. 以下是效果图: 图中包括背景图片.文字描述以及白点. 其中Vie ...
- 学习笔记_Java_day13_JSTL标签库(1、2、3、4、5、6、7、8)
1.一种标签语言 day13 l JSTL标签库(重点) l 自定义标签(理解) l MVC设计模式(重点中的重点) l Java三层框架(重点中的重点) JSTL标签库 1 什么是JSTL ...
- swift变量交换赋值
重点在& func jiaohuan(inout a: Int,inout b: Int) { let temp = a a = b b = temp } jiaohuan(&aa,b ...
- iOS 高级开发 runtime(三)
三 .动态添加方法 我们可以通过runtime动态地添加方法.那么到底啥叫动态添加方法呢?动态添加方法就是当我们程序运行时才知道我们应该调用哪个方法.我们首先需要了解这一点,当我们编写完一段代码后,我 ...
- html-----016---HTTP 状态消息
HTTP 状态消息 当浏览器从 web 服务器请求服务时,可能会发生错误. 从而有可能会返回下面的一系列状态消息: 1xx: 信息 消息: 描述: 100 Continue 服务器仅接收到部分请求,但 ...
- Hack--兼容性测试
CSS hack由于不同的浏览器,比如Internet Explorer 6,Internet Explorer 7,Mozilla Firefox等,对CSS的解析认识不一样,因此会导致生成的页面效 ...
- LOL(英雄联盟)系统鼠标速度锁定工具
最近习惯将系统的鼠标速度降低, 而提高鼠标硬件DPI来提升移动准确度, 但是LOL的客户端每次启动进入游戏后就会还原系统鼠标的移动速度, 我把情况反应给腾讯,没想到他们一点都不重视, 建议我只改游戏里 ...
- Qt之json解析
Jsoner::Jsoner(QObject *parent) : QObject(parent){ QJsonObject json; json.insert("loginna ...
- WPF窗体置于桌面最底层
在WPF中设置窗体的Topmost属性可以将窗体永远置于顶部,但是没有提供Bottommost属性将窗体置底.若果要将窗体置于桌面的最底部,就需要使用Windows API来实现了.解决方案如下: 1 ...