一、poll介绍

函数原型:

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);

struct pollfd定义:

struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};

fd:文件描述符

events:关心的事件,输入参数

revents:产生的事件,输出参数

事件类型:

POLLIN    普通或优先级带数据可读
POLLRDNORM 普通数据可读
POLLRDBAND 优先级带数据可读
POLLPRI 高优先级数据可读
POLLOUT 普通数据可写
POLLWRNORM 普通数据可写
POLLWRBAND 优先级带数据可写
POLLERR 发生错误
POLLHUP 发生挂起
POLLNVAL 描述字不是一个打开的文件

关于poll的具体用法,请见下面示例。

二、poll使用

示例1:回显服务器

/*******************************************************************************
* File Name : poll.cpp
* Author : zjw
* Email : emp3XzA3MjJAMTYzLmNvbQo= (base64 encode)
* Create Time : 2015年07月17日 星期五 09时42分11秒
*******************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <poll.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h> #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cerrno>
#include <cstring>
using namespace std; const int SERVER_PORT = ;
const int EVENT_SIZE = ;
const int RECV_SIZE = ;
const int SEND_SIZE = ; int main(int argc, char **argv)
{
int server = socket(AF_INET, SOCK_STREAM, );
struct sockaddr_in addrServer;
bzero(&addrServer, sizeof(addrServer));
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(SERVER_PORT);
addrServer.sin_addr.s_addr = INADDR_ANY; if (bind(server, (struct sockaddr*)&addrServer, sizeof(addrServer)))
{
perror("bind failed,");
return -;
} listen(server, );
cout << "listening on port:" << SERVER_PORT << " ..." << endl; struct pollfd fds[EVENT_SIZE] = {{, , }};
fds[server].fd = server;
fds[server].events = POLLIN; int ret = ;
char recvBuf[RECV_SIZE + ];
char sendBuf[SEND_SIZE + ];
while ()
{
if ((ret = poll(fds, EVENT_SIZE, )) < )
{
perror("poll failed,");
return -;
} for (int i = ; i < EVENT_SIZE; i++)
{
if (fds[i].fd == )
{
continue;
} if (fds[i].fd == server && (fds[i].revents & POLLIN))
{ // accept a new client
struct sockaddr_in addrClient;
socklen_t len = sizeof(addrClient);
int client = accept(server, (struct sockaddr*)&addrClient, &len);
if (client == -)
{
perror("accept failed,");
return -;
}
else
{
cout << "accep an new client " << client << ", ip:" << inet_ntoa(addrClient.sin_addr) << endl;
fds[client].fd = client;
fds[client].events = POLLIN;
}
}
else if (fds[i].revents & POLLIN)
{ // read event
memset(recvBuf, , RECV_SIZE + );
if ((ret = recv(fds[i].fd, recvBuf, RECV_SIZE, )) < )
{
perror("recv failed,");
return -;
}
else if (ret == )
{ // client close
close(fds[i].fd);
fds[i].fd = ;
}
else
{ // recv data
cout << "client " << fds[i].fd << " said:" << recvBuf << endl;
memset(sendBuf, , SEND_SIZE + );
sprintf(sendBuf, "You said:%s", recvBuf);
if ((ret = send(fds[i].fd, sendBuf, SEND_SIZE, )) < )
{
perror("send failed,");
return -;
}
}
}
else
{ // write event }
}
}
close(server); return ;
}

Makefile:

echo: poll.cpp
g++ -g -o $@ $< clean:
rm -rf echo

运行结果:

服务器端:

客户端1:

客户端2:

三、参考

http://www.360doc.com/content/12/0821/10/7775902_231465100.shtml

http://blog.chinaunix.net/uid-23842323-id-2656589.html

linux poll 学习的更多相关文章

  1. 嵌入式Linux驱动学习之路(十二)按键驱动-poll机制

    实现的功能是在读取按键信息的时候,如果没有产生按键,则程序休眠在read函数中,利用poll机制,可以在没有退出的情况下让程序自动退出. 下面的程序就是在读取按键信息的时候,如果5000ms内没有按键 ...

  2. Linux驱动学习步骤(转载)

    1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ls ...

  3. Linux.NET学习手记(7)

    前一篇中,我们简单的讲述了下如何在Linux.NET中部署第一个ASP.NET MVC 5.0的程序.而目前微软已经提出OWIN并致力于发展VNext,接下来系列中,我们将会向OWIN方向转战. 早在 ...

  4. Linux.NET学习手记(8)

    上一回合中,我们讲解了Linux.NET面对OWIN需要做出的准备,以及介绍了如何将两个支持OWIN协议的框架:SignalR以及NancyFX以OwinHost的方式部署到Linux.NET当中.这 ...

  5. 关于《Linux.NET学习手记(8)》的补充说明

    早前的一两天<Linux.NET学习手记(8)>发布了,这一篇主要是讲述OWIN框架与OwinHost之间如何根据OWIN协议进行通信构成一套完整的系统.文中我们还直接学习如何直接操作OW ...

  6. Linux LVM学习总结——扩展卷组VG

    Linux服务器由于应用变更或需求的缘故,有可能出现分区空间不足的情况,此时往往需要进行扩容(要增加分区的空间),而采用LVM的好处就是可以在不需停机的情况下可以方便地调整各个分区大小.如下所示,分区 ...

  7. linux的学习记录随笔

    为什么学习linux 因为操作系统是一种介质,你要接触其中的东西,首先必须要有介质,而linux在服务器端是老大哥的地位,所以呢,学习linux吧. 学习的方式 可以看视频 imooc.百度传课.网易 ...

  8. 嵌入式Linux驱动学习之路(二十七)字符设备驱动的另一种写法

    之前讲的字符设备驱动程序,只要有一个主设备号,那么次设备号无论是什么都会和同一个 struct file_operations 结构体对应. 而本节课讲的是如何在设备号相同的情况下,让不同的次设备号对 ...

  9. Linux LVM学习总结——创建卷组VG

    在Linux平台如何创建一个卷组(VG)呢?下面简单介绍一下卷组(VG)的创建步骤.本文实验平台为Red Hat Enterprise Linux Server release 6.6 (Santia ...

随机推荐

  1. Swift游戏实战-跑酷熊猫 07 平台的移动

    这节内容我们来实现平台是怎么产生移动动画的. 要点 1 利用数组存放平台 var platforms=[Platform]() 2 有新的平台产生存放进数组 platforms.append(plat ...

  2. javabean实体类对象转为Map类型对象的方法(转发)

    //将javabean实体类转为map类型,然后返回一个map类型的值 public static Map<String, Object> beanToMap(Object obj) { ...

  3. csuoj 1334: 好老师

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1334 1334: 好老师 Time Limit: 1 Sec  Memory Limit: 128 ...

  4. ofbiz进击 第六节。 --OFBiz配置之[widget.properties] 配置属性的分析

    配置内容分析如下 # -- 定义上下文使用者 -- security.context =default # -- 定义密码限制长度最小值 -- password.length.min =5 # -- ...

  5. android 测试(转)

    个人接触android的时间也不是很长,稍微总结下在做Android测试的过程中,初次接触的同学需要些什么准备,以及需要些什么知识?下面讲到的东西可能很多人会觉得很简单,但我确实碰到过有新同学对这些点 ...

  6. C++之路进阶——codevs4655(序列终结者)

    4655 序列终结者  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master      题目描述 Description 网上有许多题,就是给定一个序列,要你支持几 ...

  7. 什么是XML

    什么是 XML? XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML 标签没 ...

  8. paper 49:论文退稿?审稿人帮你总结了22个能避免的常见问题

    很多投稿出去的文章都是可上可下的.往往退稿的时候,审稿人提了一堆意见,说退稿.但是大家想过没有?如果能事先预测到这些意见,或者请懂行的人事先看过文章预测出意见,然后根据这些意见修改好了再投出去,说不定 ...

  9. c语言对文件操作完成后尽量手动关闭

    是这样的,我写了一个函数,传给函数文件名,在函数中对文件写入一些内容.在这个函数的后面没有手动使用 fclose. 当在程序中对这个函数调用两次之后,最终把要写入的文件写错了. 在第二次使用 fope ...

  10. java web sql注入测试(1)---概念概述

    在进行java web 测试时,经常会忽略的测试种类就是sql注入测试,这类缺陷造成的原因是开发技术在这方面欠缺的表现,虽然不常见,但一旦有这类缺陷,就很因此对运营的数据造成很多不必要的损失,所以,还 ...