Linux poll

poll提供的功能与select类似,不过在处理流设备时,它能够提供额外的信息。

1、函数原型

  #include <poll.h>int poll(struct pollfd fd[], nfds_t nfds, int timeout);

2、函数参数:
(1)fd:一个结构数组,struct pollfd结构如下:

struct pollfd
{int fd;              //文件描述符short events;    //请求的事件short revents;   //返回的事件
};

  events和revents是通过对代表各种事件的标志进行逻辑或运算构建而成的。events包括要监视的事件,poll用已经发生的事件填充revents。poll函数通过在revents中设置标志肌肤POLLHUP、POLLERR和POLLNVAL来反映相关条件的存在。不需要在events中对于这些标志符相关的比特位进行设置。如果fd小于0, 则events字段被忽略,而revents被置为0.标准中没有说明如何处理文件结束。文件结束可以通过revents的标识符POLLHUN或返回0字节的常规读操作来传达。即使POLLIN或POLLRDNORM指出还有数据要读,POLLHUP也可能会被设置。因此,应该在错误检验之前处理正常的读操作。
poll函数的事件标志符值
常量 说明
POLLIN 普通或优先级带数据可读
POLLRDNORM 普通数据可读
POLLRDBAND 优先级带数据可读
POLLPRI 高优先级数据可读
POLLOUT 普通数据可写
POLLWRNORM 普通数据可写
POLLWRBAND 优先级带数据可写
POLLERR 发生错误
POLLHUP 发生挂起
POLLNVAL 描述字不是一个打开的文件
  注意:后三个只能作为描述字的返回结果存储在revents中,而不能作为测试条件用于events中。
(2)第二个参数nfds:要监视的描述符的数目。

(3)最后一个参数timeout:是一个用毫秒表示的时间,是指定poll在返回前没有接收事件时应该等待的时间。如果  它的值为-1,poll就永远都不会超时。如果整数值为32个比特,那么最大的超时周期大约是30分钟。 INFTIM:永远等待;0:立即返回,不阻塞进程;>0:等待指定毫秒数。

#ifndef _POLL_H_
#define _POLL_H_#include "wrap.h"
#include "client_list.h"
#include "server_queue.h"#define SERVER_PORT     6780
#define MAXLINE         100
#define OPEN_MAX        65535
#define TCP_FRAME_SIZE  1200typedef struct
{int sockfd;  // server socketint port;    // server portstruct sockaddr_in addr; // server addrint maxi;  // poll maxstruct pollfd event_list[OPEN_MAX]; // poll all event server_queue_t send_queue; // server send data queue to clientserver_queue_t recv_queue; // server recv data queue from clientpthread_t send_thread;pthread_t recv_thread;client_t *client;  // client list -- save all client info
} server_t;/* recv and send queue frame */
typedef struct
{int sockfd;  // client socketuint16_t length;char data[TCP_FRAME_SIZE];
} __packed tcp_frame_t;//==========================================================
server_t *SocketInit(void);#endif /* _POLL_H_ */
#include "poll.h"
#include "debug.h"static server_t *socket_init(void)
{int opt = 1, i;server_t *current;current = (server_t *)malloc(sizeof(server_t));current->port = SERVER_PORT;current->sockfd = Socket(AF_INET, SOCK_STREAM, 0);// SOL_SOCKET: port can same, ip notSetsockopt(current->sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));current->addr.sin_family = AF_INET;current->addr.sin_port = htons(current->port);current->addr.sin_addr.s_addr = INADDR_ANY;Bind(current->sockfd, (struct sockaddr *)¤t->addr, sizeof(current->addr));Listen(current->sockfd, MAXLINE);current->event_list[0].fd = current->sockfd;current->event_list[0].events = POLLIN;for(i = 1; i < OPEN_MAX; ++i){current->event_list[i].fd = -1;}current->maxi = current->sockfd;ServerQueueInit(&current->send_queue, TCP_FRAME_SIZE);ServerQueueInit(&current->recv_queue, TCP_FRAME_SIZE);return current;
}static void socket_accept(server_t *arg)
{server_t *current = arg;struct sockaddr_in addr;int len = sizeof(struct sockaddr_in), i;int new_fd = Accept(current->sockfd, (struct sockaddr *)&addr, &len);debug("new connection client_fd ( %d ) %s: %d\n", new_fd, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));for(i = 0; i < OPEN_MAX; ++i){if(current->event_list[i].fd < 0){// add new_fd to event_list current->event_list[i].fd = new_fd;current->event_list[i].events = POLLIN;break;}}if(OPEN_MAX == i){printf("too many connects\n");Close(new_fd);return;}if(i > current->maxi){current->maxi = i;}/* add client node */client_t *node = (client_t *)malloc(sizeof(client_t));node->sockfd = new_fd;memcpy(&node->addr, &addr, sizeof(struct sockaddr_in));ClientAdd(node);
}static void socket_recv(server_t *arg, int ret)
{server_t *current = arg;int i, sockfd, length = 0;tcp_frame_t write;for(i = 1; i <= current->maxi; ++i){if((sockfd = current->event_list[i].fd) < 0){continue;}if(current->event_list[i].revents & (POLLIN | POLLERR)){length = recv(sockfd, write.data, TCP_FRAME_SIZE, 0);if(0 == length){/* delete client node, close connect socket */debug("client[%d] close\n", sockfd);ClientDel(sockfd);Close(sockfd);continue;}else if(length > 0){write.sockfd = sockfd;write.length = length;server_debug(write.data, write.length);// add data to recv_queue, pop in other, if(ServerQueueWrite(&current->recv_queue, (uint8_t *)&write, sizeof(tcp_frame_t)) == 0){debug("push failure...queue full...\n");}}if(--ret <= 0){break;}}}
}static void *server_recv_thread(void *arg)
{server_t *current = (server_t *)arg;while(1){int timeout = 3000;int ret = Poll(current->event_list, current->maxi, timeout);if(current->event_list[0].revents & POLLIN){socket_accept(current); // a new connect come}if(--ret < 0){continue;}socket_recv(current, ret); // a exsit connect send data to us}Close(current->sockfd);return NULL;
}static void *server_send_thread(void *arg)
{server_t *current = (server_t *)arg;tcp_frame_t *read = NULL;while(1){//read = (tcp_frame_t*)ServerQueueRead(&current->send_queue, sizeof(tcp_frame_t));if(read != NULL){//server_debug(read->data, read->length);}usleep(100);}return NULL;
}server_t * SocketInit(void)
{server_t *current = socket_init();debug("create thread...\r\n");pthread_create(&current->send_thread, NULL, server_send_thread, current);pthread_create(&currentt->recv_thread, NULL, server_recv_thread, current);return current;
}

Linux poll相关推荐

  1. linux poll函数 实现,Linux select/poll/epoll 原理(一)实现基础

    本序列涉及的 Linux 源码都是基于 linux-4.14.143 . 1. 文件抽象 与 poll 操作 1.1 文件抽象 在 Linux 内核里,文件是一个抽象,设备是个文件,网络套接字也是个文 ...

  2. linux poll 作用,Linux中poll机制的理解

    首先分析下应用程序的执行过程: int main(int argc, char **argv) { int fd; unsigned char key_val; int ret; struct pol ...

  3. linux poll机制 阻塞,linux poll机制使用(一)

    一.poll机制的作用 1.poll机制的作用 在前面的使用中断的的方式来读取按键值(linux 中断管理(四)).使用这种方式读取按键,如果按键没有按下的时候,应用程序会一直处于睡眠的状态.如果想要 ...

  4. Linux Poll机制

    一.Poll什么? Poll某个fd特定的event. 二.event的总类包括? POLLIN – This bit must be set if the device can be read wi ...

  5. linux poll cpu过高,CPU占用过高问题排查

    前几天发现测试环境的CPU一直很高,于是就去排查了一下原因,之前在程序管理里面介绍过,可以通过top命令查看linux系统进程的资源占用.于是运行top命令如下: top 从上图中可以看到其中有一个线 ...

  6. linux poll in,Linux poll机制详细讲解

    所有的系统调用,基于都可以在它的名字前加上"sys_"前缀,这就是它在内核中对应的函数.比如系统调用open.read.write.poll,与之对应的内核函数为:sys_open ...

  7. linux的poll_wait函数,Linux poll机制详细讲解

    所有的系统调用,基于都可以在它的名字前加上"sys_"前缀,这就是它在内核中对应的函数.比如系统调用open.read.write.poll,与之对应的内核函数为:sys_open ...

  8. linux poll in,Linux poll函数深入理解

    poll函数与select函数差不多 函数原型: #include int poll(struct pollfd fd[], nfds_t nfds, int timeout); struct pol ...

  9. linux下poll和epoll内核源代码剖析

    作者:董昊 博客链接http://donghao.org/uii/ poll和epoll的使用应该不用再多说了.当fd很多时,使用epoll比poll效率更高. 我们通过内核源码分析来看看到底是为什么 ...

最新文章

  1. python3 抛出异常_Python3 异常
  2. AC日记——食物链 codevs 1047
  3. 字母全排列快速算法C代码
  4. ABAP方法的exporting类型参数,需要在方法实现最开始显式初始化么
  5. django-models类索引外键时候的related_name属性作用
  6. 迷惑!博士生发Nature造假,怕被调查扔掉实验室万元电脑
  7. 两个简单的Demo示例向读者展示Flash和ASP.NET交互原理以及过程
  8. 网络渗透测试(2)——使用nmap扫描微信服务器
  9. oracle+生成+sql语句,Oracle使用SQL语句生成日历的实现方法
  10. vue项目eslint配置
  11. 解决从PDF复制到Word中的英文字母变成宋体格式的问题
  12. JAVA之进制转换(全)
  13. JSFL自动绘画_2_三阶贝塞尔曲线画线
  14. ABP教程-打造一个《电话簿项目》-目录-MPA版本-基于ABP1.13版本
  15. Topic 7. 临床预测模型--Cox回归
  16. 制作U盘安装XP系统
  17. 关于WIN10开机启动慢的一些问题解决
  18. UltraEdit 27.0.0.24 中文版 — 文本代码编辑工具
  19. 长期激励应占“一席之地” 穆穆-movno1
  20. CentOS集群上安装Ganglia-3.6.1监控

热门文章

  1. java开发环境搭建--写给java新手
  2. Android 自定义View以及ValueAnimator学习
  3. 使用tmpfs存放MySQL的临时文件的问题一则
  4. jQuery:仿MSN网站的tab效果
  5. akshare 布林通道策略
  6. 蒙特卡洛分析 pmp_PMP基础名词介绍 | 59. 实施定量风险分析
  7. Linux基本操作【作业】
  8. php 计算数据偏离度,关于偏离度的测算方法
  9. python leetcode_leetcode 介绍和 python 数据结构与算法学习资料
  10. Implicit declaration of function 'NSFileTypeForHFSTypeCode' is invalid in C99