介绍

相对于select做了一些改进, 突破了1024, select是需要一张表, 并且需要遍历其中改变的描述符

而poll将这些内容封装成一个结构体, 其中包含了fd和需要监控的事件, 如果发生改变则会更改revents值

API:

struct pollfd {

int fd; // 文件描述符

short events; // 监控的事件

short revents;// 监控事件中满足条件返回的事件

};

int poll(struct pollfd fds[], nfds_t nfds, int timeout);

fds[] 数组地址, select需要一张表, 而这里需要一个结构体数组, 每个结构体中有一个fd

nfds 需要检测文件描述符对应结构体在数组中的下标+1, 表示一个检测的范围

timeout

1.-1 永久阻塞

2.0:调用完成立即返回

3.>0: 等待的时长, 毫秒

返回值:IO发生变化的文件描述符的个数

代码

检测同上一篇即可

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define SERV_PORT 8888

int main(int argc, const char * argv[]) {

int lfd, cfd; //用于监听和通信的文件描述符

struct sockaddr_in serv_addr, clien_addr;//sockaddr结构体

//结构体长度

socklen_t serv_len = sizeof(serv_addr), clien_len = sizeof(clien_addr);

//创建套接字

lfd = socket(AF_INET, SOCK_STREAM, 0);

//初始化服务器 serv_addr

memset(&serv_addr, 0, serv_len);

serv_addr.sin_family = AF_INET;

serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);//所有IP

serv_addr.sin_port = htons(SERV_PORT);//设置端口

//设置重用端口

int opt = 1;

setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

//绑定IP和端口

bind(lfd, (struct sockaddr*)&serv_addr, serv_len);

// 设置同时监听的最大个数

listen(lfd, 64);

printf("Start accept ......\n");

//poll结构体数组

struct pollfd allfd[1024];

int max_index = 0; // nfds 检测的范围时用

//初始化结构体数组, 将监听事件设置为POLLIN, 并且从lfd开始监听

for (int i = 0; i < 1024; ++i) {

allfd[i].fd = -1; //初始化成无效的值

allfd[i].events = POLLIN; //如果需要监听其他的则赋值对应的宏即可

}

allfd[0].fd = lfd; //默认从lfd之后的文件描述符开始监听

int i = 0;

while (1) {

//第一次只有一个-lfd, 主要用于检测有没有新的客户端连接

int ret = poll(allfd, max_index+1, -1);

if (ret == -1) {

perror("poll error");

exit(1);

}

//判断有没有客户端连接

if (allfd[0].revents & POLLIN) {

//接受连接请求

cfd = accept(lfd, (struct sockaddr *)&clien_addr, &clien_len);

char ipbuf[128];

printf("new client link IP: %s, port: %d\n", inet_ntop(AF_INET, &clien_addr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)),

ntohs(clien_addr.sin_port));

//将刚刚接受的连接请求对应的客户端的文件描述符加到数组中

for (int i = 0; i < 1024; ++i) {

if (allfd[i].fd == -1) {

allfd[i].fd = cfd;

break;

}

}

i++;

//更新要监听的范围

max_index = max_index < i ? i : max_index;

}

//遍历数组, 查看发生改变的客户端, 并做出对应操作

//从1开始监听, 因为0位置的是lfd

for (int i = 1; i <= max_index; ++i) {

int fd = allfd[i].fd;

if(fd == -1) { continue; }

if(allfd[i].revents & POLLIN) {

//接受数据

char buf[1024] = {0};

int len = (int)recv(fd, buf, sizeof(buf), 0);

if(len == -1) {

perror("recv error");

exit(1);

} else if(len == 0) {

allfd[i].fd = -1; //重新置为无效, 系统检测到无效的话会跳过

close(fd);

printf("客户端已经主动断开连接。。。\n");

} else {

printf("recv buf = %s\n", buf);

for(int k = 0; k < len; ++k) {

buf[k] = toupper(buf[k]); //变为大写

}

printf("buf toupper: %s\n", buf);

send(fd, buf, strlen(buf)+1, 0);

}

}

}

}

return 0;

}

linux windows并发模型,Linux并发服务器模型四 -- poll相关推荐

  1. linux设备驱动模型-linux驱动开发第5部分-朱有鹏-专题视频课程

    linux设备驱动模型-linux驱动开发第5部分-4285人已学习 课程介绍         本课程是linux驱动开发的第5个课程,主要内容是linux的设备驱动模型,包括总线.类.设备.驱动等概 ...

  2. Linux / Windows Subsystem for Linux (WSL) 安装 ADB (Android Debug Bridge,Android 调试桥)

    Linux / Windows Subsystem for Linux (WSL) 安装 ADB (Android Debug Bridge,Android 调试桥) Android 开发者网站 ht ...

  3. linux内核基本模型,Linux设备模型(1)_基本概念

    Linux设备模型(1)_基本概念 作者:wowo 发布于:2014-2-27 17:01 分类:统一设备模型 1. 前言 在"Linux内核的整体架构"中,蜗蜗有提到,由于Lin ...

  4. windows10 安装linux,windows 10安装linux(ubuntu)子系统

    windows10安装ubuntu子系统系统 之前一直在虚拟机中使用linux系统,但是不是很方便,后来发现windows下也有了linux系统.感觉还不错 1. 打开windows应用市场micro ...

  5. windows 连Linux,Windows下访问Linux资源

    Windows下访问Linux资源 在Red Hat Linux中,借助Samba服务在Windows下访问Linux的资源也是很容易的,依次单击"主菜单" "系统设置& ...

  6. linux windows 结构体,Linux下C语言——结构体对齐

    结构体对齐的步骤: 1.结构体各成员对齐 2.整个结构体圆整 结构体对齐的特定对齐值: 1.自身对齐值: 自身对齐值就是结构体变量里每个成员的自身大小; 2.指定对齐值: 指定对齐值是由宏#pragm ...

  7. Linux -- Windows右键开启Linux子系统Bash

    好容易安装完 linux 子系统,发现对于一些必须在 linux 下使用的软件或者其他的东东的使用实在是方便了不少,即少了运行虚拟机的卡慢内存占比高,也少了 linux/windows 双系统的切换, ...

  8. linux 内核驱动模型,linux设备驱动模型架构分析 一

    linux设备驱动模型架构分析 一 发布时间:2018-07-04 15:14, 浏览次数:584 , 标签: linux 概述 LDD3中说:"Linux内核需要一个对系统结构的一般性描述 ...

  9. linux windows死机,linux死机的处理方式

    简述 据传闻manjaro简单又好用,安装以后果然,不说别的,单单就软件包的数量就吊打,又有QQ又有微信,还有cajviewer. 然而不管怎么着,死机是最为常见的现象了.估计是因为我用了KDE.Li ...

最新文章

  1. macOS完全卸载Android Studio方法
  2. 虚拟机与系统文件互传(VMware Tools)的使用
  3. amd显卡风扇调节_和AMD首席游戏架构师Frank Azor聊聊RX 6000系列显卡那些事儿
  4. 杭电信工2018期末c语言试卷,2018C程序设计期末试卷(2018杭电A卷).doc
  5. CPU资源和可用内存大小
  6. 安卓和Linux动态库一样吗,在Linux环境下编译Android下的最新版ffmpeg+x264单个动态库(.so)...
  7. 畅通工程 HDU - 1863
  8. vue调用手机相机相册_详解Vue调用手机相机和相册以及上传
  9. 51单片机 16*64LED单红点阵屏驱动测试,上位机改字软件免费版
  10. 分布式面试 - 集群部署时的分布式 session 如何实现?
  11. WebService的简单实现
  12. Kubernetes 小白学习笔记(17)--集群安全-APIServer的安全模型
  13. UVA 10369 - Arctic NetWork (求最小生成树)
  14. 最新emoji表情代码大全_三十而已表情包下载-三十而已表情包大全最新下载
  15. floppy计算机专业术语,计算机专业术语解释
  16. gcc 如何编译cpp文件啊
  17. 题目 1549: 盾神与积木游戏
  18. JavaScript基础系列之一 快速入门
  19. ios16更新了什么内容 ios16更新内容汇总
  20. Jenkins的安装及使用

热门文章

  1. pandas使用replace函数和正则表达式移除dataframe字符串数据列中尾部指定模式字符串(Removing trailing substring in dataframe)
  2. 机器学习类别/标称(categorical)数据处理:独热编码(One Hot Encoding)
  3. trimmomatic对fastq质控
  4. angular4创建html,angular 4减少html内容
  5. ISLR_StatisticalLearning
  6. threadlocal存连接对象的目的_面试官:知道ThreadLocal嘛?谈谈你对它的理解?
  7. java代码内创建mysql索引_Java Mysql数据库创建视图、索引、备份和恢复
  8. python opencv 得到图片路径image_path的宽wide、高heigh和深度deep
  9. Caffe 关于 LetNet-5 之 lenet_solver.prototxt 解析
  10. LeetCode 104. Maximum Depth of Binary Tree--二叉树高度--递归或迭代--C++,Python解法