Linux网络编程---I/O复用模型之poll

https://blog.csdn.net/men_wen/article/details/53456474

Linux网络编程—I/O复用模型之poll

1.函数poll

poll系统调用和select类似,也是在指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪者。

#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);
//返回值:若成功,返回就绪的描述符个数,若超时则为0,若出错则为-1
  • fds是指向一个pollfd结构第一个元素的指针。每一个元素都是pollfd结构类型,用于测试某个给定描述符fd的条件
struct pollfd {int   fd;         /* file descriptor */short events;     /* requested events */short revents;    /* returned events */
};

要测试的条件在events中指定,函数相应的revents成员返回该描述符的状态,一个为调用值,一个为返回结果,这与select的传入传出参数不同。 
events和revents可以设置以下常量的一个或多个的按位或结果:

POLLIN      //普通或带外优先数据可读,即POLLRDNORM | POLLRDBAND
POLLRDNORM  //数据可读
POLLRDBAND  //优先级带数据可读
POLLPRI     //高优先级可读数据
POLLOUT     //普通或带外数据可写
POLLWRNORM  //数据可写
POLLWRBAND  //优先级带数据可写
//下面三个revents不包含
POLLERR     //发生错误
POLLHUP     //发生挂起
POLLNVAL    //描述字不是一个打开的文件
  • out指定poll函数返回前等待多长时间,它是一个指定应等待毫秒数的正值。

|timeout值|说明| 
|:-:|:-:| 
|-1|永远等待| 
|0|立即返回,不阻塞进程| 
|>0|等待指定数目的毫秒数|

  • nfds 是监控数组中有多少文件描述符需要被监控

如果我们不关心某个特定的描述符,那么可以把与它对应的pollfd结构的fd成员设置为一个负值。poll函数会忽略这样的pollfd结构的events成员,返回时将其revents成员的值置为0。

select模型最多可以创建一个1024个文件描述符大小的集合,这是因为受到fd_set的固定数据类型的限制,而poll则没有这样的问题,因为分配一个pollfd结构的数组并把数组中的元素通知内核称为调用者的责任。但是poll模型任然使用的是轮询模型,效率比较低下。

2. poll模型实现

2.1 服务器端

#include "wrap.h"
#include <poll.h>
#include <limits.h>
#include <sys/stropts.h>#define MAXLINE         1024
#define INFTIM          -1
#define OPEN_MAX        3000
int main(int argc, char *argv[])
{int i, maxi, listenfd, connfd, sockfd;int nready;ssize_t n;char buf[MAXLINE];socklen_t clilen;struct pollfd client[OPEN_MAX];struct sockaddr_in clientaddr;listenfd = start_ser(argv[1], argv[2]);//监听文件描述符  该函数参考selectclient[0].fd = listenfd;//将监听文件描述符加入pollfd数组中client[0].events = POLLIN;//设置为输入可读for(i = 1; i < OPEN_MAX; i++){//初始化结构体数组client[i].fd = -1;}maxi = 0;while(1){nready = poll(client, maxi+1, INFTIM);  //阻塞等待注册时间发生if(client[0].revents & POLLIN){//当监听文件描述符响应有新连接请求clilen = sizeof(clientaddr);connfd = Accept(listenfd, (struct sockaddr *)&clientaddr, &clilen);//接受新客户for(i = 1; i < OPEN_MAX; i++){if(client[i].fd < 0){client[i].fd = connfd;  //把新客户的文件描述符加入数组break;}}if(i == OPEN_MAX){      //连接新客户上限Close(connfd);perr_exit("too many clients");}client[i].events = POLLIN;      //新客户端的处理事件if(i > maxi){maxi = i;       //更新最大值}if(--nready == 0){      //没有可读的描述符跳过本次循环continue;}}for(i = 1; i <= maxi; i++){     //请求所有客户端的数据if((sockfd = client[i].fd) < 0){continue;}if(client[i].revents & POLLIN){ //POLLIN事件发生memset(buf, '\0', MAXLINE);if((n = Read(sockfd, buf, MAXLINE-1)) < 0){if(errno == ECONNRESET){        //当客户端发送resetClose(sockfd);client[i].fd = -1;}else{perr_exit("read err");}}else if(n == 0){Close(sockfd);client[i].fd = -1;}else{printf("client : %s\n", buf);}if(--nready == 0){      //没有可读的描述符跳过本次循环break;}}}}Close(connfd);Close(listenfd);return 0;
}

2.2客户端

#include "wrap.h"int main(int argc, char *argv[])
{struct sockaddr_in serveraddr;int connfd;connfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&serveraddr, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(atoi(argv[2]));inet_pton(AF_INET, argv[1], &serveraddr.sin_addr);Connect(connfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));char buf[1024];while((fgets(buf, 1024, stdin)) != NULL){Write(connfd, buf, strlen(buf));}Close(connfd);return 0;
}

2.3程序测试结果

这里写图片描述

这里写图片描述

这里写图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383759.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FFT模板

整理了一下&#xff0c;自己写了一下模板 const double PIacos(-1.0); struct complex {double r,i;complex(double _r0,double _i0):r(_r),i(_i){}complex operator (const complex &b) {return complex(rb.r,ib.i);}complex operator -(const complex &b) {return c…

Linux网络编程---I/O复用模型之epoll

https://blog.csdn.net/men_wen/article/details/53456474 Linux网络编程—I/O复用模型之epoll 1. epoll模型简介 epoll是Linux多路服用IO接口select/poll的加强版&#xff0c;e对应的英文单词就是enhancement&#xff0c;中文翻译为增强&#xff0c;加强&#xff0c;提高&…

POJ 1741tree-点分治入门

学习了一下点分治&#xff0c;如果理解有误还请不吝赐教。 为了快速求得树上任意两点之间距离满足某种关系的点对数&#xff0c;我们需要用到这种算法。 点分治是树上的一种分治算法&#xff0c;依靠树和子树之间的关系进行分治从而降低复杂度。 和其他树上的算法有一些区别…

基于单链表的生产者消费者问题

『生产者与消费者问题分析』「原理」生产者生产产品&#xff0c;消费者消费产品。产品如果被消费者消费完了&#xff0c;同时生产者又没有生产出产品&#xff0c;消费者 就必须等待。同样的&#xff0c;如果生产者生产了产品&#xff0c;而消费者没有去消费&#x…

C++智能指针(一)智能指针的简单介绍

https://blog.csdn.net/nou_camp/article/details/70176949C智能指针 在正式了解智能指针前先看一下下面的一段代码 #include<iostream> using namespace std; class A { public:A():_ptr(NULL), _a(0){}~A(){} public:int* _ptr;int _a; };void test() {A a;int *p1 ne…

聪聪可可-点分治

聪聪和可可是兄弟俩&#xff0c;他们俩经常为了一些琐事打起来&#xff0c;例如家中只剩下最后一根冰棍而两人都想吃、两个人都想玩儿电脑&#xff08;可是他们家只有一台电脑&#xff09;……遇到这种问题&#xff0c;一般情况下石头剪刀布就好了&#xff0c;可是他们已经玩儿…

C++智能指针(二)模拟实现三种智能指针

https://blog.csdn.net/nou_camp/article/details/70186721在上一篇博客中提到了Auto_ptr(C智能指针&#xff08;一&#xff09;)&#xff0c;下面进行模拟实现Auto_ptr 采用类模板实现 #include<iostream> using namespace std; template<class T> class Autoptr …

Prime Distance On Tree-树分治+FFT

题目描述 Problem description. You are given a tree. If we select 2 distinct nodes uniformly at random, what’s the probability that the distance between these 2 nodes is a prime number? Input The first line contains a number N: the number of nodes in this…

C++智能指针(三)总结

https://blog.csdn.net/nou_camp/article/details/70195795 在上一篇博客中&#xff08;C智能指针&#xff08;二&#xff09;&#xff09;模拟实现了三种智能指针。 其中最好的就是shared_ptr,但是这并不代表它就是最完美的&#xff0c;它也有问题&#xff0c;这个问题就是循环…

POJ2114-Boatherds-树分治

题目描述 Boatherds Inc. is a sailing company operating in the country of Trabantustan and offering boat trips on Trabantian rivers. All the rivers originate somewhere in the mountains and on their way down to the lowlands they gradually join and finally th…

c++11 你需要知道这些就够了

https://blog.csdn.net/tangliguantou/article/details/50549751c11新特性举着火把寻找电灯今天我就权当抛砖引玉&#xff0c;如有不解大家一起探讨。有部分内容是引用自互联网上的内容&#xff0c;如有问题请联系我。T&& 右值引用 std::move 右值引用出现之前我们只能…

HDU5977-Garden of Eden-树分治+FWT

题目描述 When God made the first man, he put him on a beautiful garden, the Garden of Eden. Here Adam lived with all animals. God gave Adam eternal life. But Adam was lonely in the garden, so God made Eve. When Adam was asleep one night, God took a rib fro…

C++11新特性学习

https://blog.csdn.net/tennysonsky/article/details/778170481、什么是C11C11标准为C编程语言的第三个官方标准&#xff0c;正式名叫ISO/IEC 14882:2011 - Information technology -- Programming languages -- C。在正式标准发布前&#xff0c;原名C0x。它将取代C标准第二版I…

C++ override 关键字用法

override关键字作用&#xff1a; 如果派生类在虚函数声明时使用了override描述符&#xff0c;那么该函数必须重载其基类中的同名函数&#xff0c;否则代码将无法通过编译。举例子说明struct Base {virtual void Turing() 0;virtual void Dijkstra() 0;virtual void VNeumann…

Gym - 101981I-MagicPotion-最大流

题目描述 There are n heroes and m monsters living in an island. The monsters became very vicious these days, so the heroes decided to diminish the monsters in the island. However, the i-th hero can only kill one monster belonging to the set Mi. Joe, the st…

c++仿函数 functor

https://www.cnblogs.com/decade-dnbc66/p/5347088.html内容整理自国外C教材先考虑一个简单的例子&#xff1a;假设有一个vector<string>&#xff0c;你的任务是统计长度小于5的string的个数&#xff0c;如果使用count_if函数的话&#xff0c;你的代码可能长成这样&#…

HDU4812-D Tree-树分治

题目描述 There is a skyscraping tree standing on the playground of Nanjing University of Science and Technology. On each branch of the tree is an integer (The tree can be treated as a connected graph with N vertices, while each branch can be treated as a v…

成为C++高手之实战项目

https://blog.csdn.net/niu_gao/article/details/51458721 在内存中模拟出一副牌&#xff0c;然后模拟洗牌&#xff0c;发牌等动作。 流程是这样的&#xff1a;构建一副牌保存到一个数组中—洗牌—创建玩家—向玩家发牌–输出每个玩家的牌。 #include <stdio.h> #include…

C++中String类的实现

https://www.cnblogs.com/zhizhan/p/4876093.html原文&#xff1a;http://noalgo.info/382.html String是C中的重要类型&#xff0c;程序员在C面试中经常会遇到关于String的细节问题&#xff0c;甚至要求当场实现这个类。只是由于时间关系&#xff0c;可能只要求实现构造函数、…

Ubuntu软件更新失败

刚安装好Ubuntu以后需要将系统的软件都更新一下&#xff0c;但是遇到一个问题就是下载仓库信息失败&#xff0c;大概是这个样子的错误&#xff1a; 经国遇到这样的问题可以试一下下面这个命令&#xff1a; sudo rm -rf /var/lib/apt/lists/* sudo apt-get update参考网址&…