函数select、poll
函数select
select函数:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
参数:
- nfds:监控的文件描述符集里最大文件描述符加1,因为此参数会告诉内核检测前多少个文件文件描述符
- readfs:监控有读数据到达文件描述符集合,传入传出参数
- writefds:监控写数据到达文件描述符集合,传入传出参数
- exceptfds:监控异常发生到达文件描述符集合,如带外数据到达异常,传入传出参数
- timeout:定时阻塞监控时间。
void FD_CLR(int fd, fd_set *set); // 把文件描述符集里fd位清0
int FD_ISSET(int fd, fd_set *set); // 测试文件描述符集里fd是否置1
void FD_SET(int fd, fd_set *set); // 把文件描述符集合里fd位置1
void FD_ZERO(fd_set *set); // 把文件描述符集合里所有位清0
1. 测试代码:
- 服务端
//server.c
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/select.h>
#include "wrap.h" #define SERV_PROT 6666 int main(int argc, char *argv[])
{
int i, j, n, nread; int maxfd = ;
int listenfd, connfd;
char buf[BUFSIZ]; struct sockaddr_in clie_addr, serv_addr;
socklen_t clie_addr_len;
listenfd = Socket(AF_INET, SOCK_STREAM, ); int opt = ;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(SERV_PROT);
Bind(listen, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
Listen(listenfd, ); fd_set rset, allset;
maxfd = listenfd;
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
while ()
{
rset = allset;
nread = select(maxfd + , &rset, NULL, NULL, NULL); //每次循环都从新设置select监控信号集
if(nread < )
perr_exit("select error"); if (FD_ISSET(listenfd, &rset)) //说明有新的客户端连接请求
{
clie_addr_len = sizeof(clie_addr);
connfd = Accept(listenfd, (struct sockaddr *)&clie_addr, &clie_addr_len); FD_SET(connfd, &allset); //向监控文件描述符集合allset添加新的文件描述符connfd if (maxfd < connfd)
maxfd = connfd; if ( == --nread) //说明select只返回一个,并且listenfd,后续执行无须执行
continue;
}
for (i = listenfd + ; i <= maxfd; i++)
{
if (FD_ISSET(i, &rset))
{
if ((n = Read(i, buf, sizeof(buf))) == ) //当client关闭链接时, 服务端也关闭对应链接
{
Close(i);
FD_CLR(i, &allset); //解除select对此文件描述符的监控
}
else if(n == -)
perr_exit("read error");
for (j = ; j < n; ++j)
buf[j] = toupper(buf[j]);
Write(i, buf, n);
}
}
}
Close(listenfd);
return ;
}
- 客户端
//client.c
#include <arpa/inet.h>
#include "wrap.h" #define SERV_IP "192.168.245.139"
#define SERV_PORT 6666 int main(void)
{
int sfd, len;
struct sockaddr_in serv_addr;
char buf[BUFSIZ];
sfd = Socket(AF_INET, SOCK_STREAM, );
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr);
serv_addr.sin_port = htons(SERV_PORT);
Connect(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); while ()
{
fgets(buf, sizeof(buf), stdin);
int r = Write(sfd, buf, strlen(buf));
printf("Write r ======== %d\n", r);
len = Read(sfd, buf, sizeof(buf));
printf("Read len ========= %d\n", len);
Write(STDOUT_FILENO, buf, len);
}
Close(sfd);
return ;
}
代码下载地址:链接
输出结果:
函数select、poll的更多相关文章
- select()/poll() 的内核实现
mark 引用:http://janfan.cn/chinese/2015/01/05/select-poll-impl-inside-the-kernel.html 文章 select()/poll ...
- 知识联结梳理 : I/O多路复用、EPOLL(SELECT/POLL)、NIO、Event-driven、Reactor模式
为了形成一个完整清晰的认识,将概念和关系梳理出来,把坑填平. I/O多路复用 I/O多路复用主要解决传统I/O单线程阻塞的问题.它通过单线程管理多个FD,当监听的FD有状态变化的时候的,调用回调函数, ...
- Linux下select&poll&epoll的实现原理(一)
最近简单看了一把 linux-3.10.25 kernel中select/poll/epoll这个几个IO事件检测API的实现.此处做一些记录.其基本的原理是相同的,流程如下 先依次调用fd对应的st ...
- Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)
一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ...
- 多进程、协程、事件驱动及select poll epoll
目录 -多线程使用场景 -多进程 --简单的一个多进程例子 --进程间数据的交互实现方法 ---通过Queues和Pipe可以实现进程间数据的传递,但是不能实现数据的共享 ---Queues ---P ...
- Python自动化 【第十篇】:Python进阶-多进程/协程/事件驱动与Select\Poll\Epoll异步IO
本节内容: 多进程 协程 事件驱动与Select\Poll\Epoll异步IO 1. 多进程 启动多个进程 进程中启进程 父进程与子进程 进程间通信 不同进程间内存是不共享的,要想实现两个进程间 ...
- select,poll,epoll的归纳总结区分
Select.Poll与Epoll比较 以下资料都是来自网上搜集整理.引用源详见文章末尾. 1 Select.Poll与Epoll简介 Select select本质上是通过设置或者检查存放fd标志位 ...
- [转载] Linux下多路复用IO接口 epoll select poll 的区别
原地址:http://bbs.linuxpk.com/thread-43628-1-1.html 废话不多说,一下是本人学习nginx 的时候总结的一些资料,比较乱,但看完后细细揣摩一下应该就弄明白区 ...
- select poll使用
select poll使用 2.1. 怎样管理多个连接?“我想同一时候监控一个以上的文件描写叙述符(fd)/连接(connection)/流(stream),应该怎么办?” 使用 select ...
随机推荐
- java中equals,hashcode和==的区别
https://www.cnblogs.com/kexianting/p/8508207.html
- SpringMVC中请求路径参数使用正则表达式
@GetMapping("/user/{id:\\d+}") //使用正则指定Id为数字 public User getInfo(@PathVariable String id){ ...
- liunx 安装Zabbix的心酸历程
作者:邓聪聪 为了工作之需要,在系统服务方面不断的摸爬打滚,有了这样点点滴滴的经验,留后在使用! 插件网盘取. 链接: https://pan.baidu.com/s/1i5u0ed3 密码: rx ...
- bootstrap登录界面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- ROS入门学习
ROS学习笔记 ROS入门网站; ROS入门书籍 ROS主要包含包括功能包.节点.话题.消息类型和服务; ROS功能包/软件包(Packages) ROS软件包是一组用于实现特定功能的相关文件的集合, ...
- SIOCGMIIPHY 和 SIOCSMIIREG 命令
使用ioctl命令时,可以看到上述两个命令的存在, 在头文件 include/linux/sockios.h,定义如下: #define SIOCETHTOOL 0x8946 /* ...
- jqueryui插件slider的简单使用
<!DOCTYPE html> <html> <head> <title>slider</title> <meta charset=& ...
- 51nod--1298 (计算几何基础)
题目: 1298 圆与三角形 题目来源: HackerRank 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出圆的圆心和半径,以及三角形的三个顶点,问圆 ...
- 如何在eclipse中对项目进行重新编译
有时由于eclipse异常关闭,当我们重启Eclipse,在启动项目时,会报错,说:ClassNotFound类似的错误,引起这种问题的原因可能是由于,Eclipse异常关闭引起的. 解决:在一个项目 ...
- 浅谈深度优先和广度优先(scrapy-redis)
首先先谈谈深度优先和广度优先的定义 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法.沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的 ...