linux 网络编程 select函数用法

【Linux网络编程】select多路复用 我们上节课讲解了服务端的编程(Linux服务端编程初体验)本节课要讲的是select提示:以下是本篇文章正文内容,下面案例可供参考。 阅读详情

       Select 在Socket 编程中还是比较重要的,可是对于初学Socket 的人来说都不太爱用Select 写程序,他们只是习惯写诸如 connect 、accept 、recv 或recvfrom 这样的阻塞程序(所谓阻塞方式block ,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回) 。


可是使用 Select 就可以完成非阻塞(所 谓 非阻塞方式 non- block ,就是 进 程或 线 程 执 行此函数 时 不必非要等待事件的 发 生,一旦 执 行肯定返回,以返回 值 的不同来反映函数的 执 行情况,如果事件 发 生 则 与阻塞方式相同,若事件没有 发 生 则 返回一个代 码 来告知事件未 发 生,而 进 程或 线 程 继续执 行,所以效率 较 高)方式工作的程序,它能 够监视 我 们 需要 监视 的文件描述符的 变 化情况 —— 读 写或是异常。


下面详细介绍一下!


Select
的函数格式( 我所说的是Unix 系统下的伯克利socket 编程,和windows 下的有区别,一会儿说明) :
int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);
先说明两个结构体:
第一,struct fd_set 可以理解 为 一个集合, 这 个集合中存放的是文件描述符(filedescriptor) ,即文件句柄 ,这可以是我们所说的普通意义的文件,当然Unix 下任何设备、管道、FIFO 等都是文件形式,全部包括在内,所以毫无疑问一个socket 就是一个文件,socket 句柄就是一个文件描述符。
fd_set
集合可以通过一些宏由人为来操作,比如
清空集合FD_ZERO(fd_set *) ;
将一个给定的文件描述符加入集合之中FD_SET(int ,fd_set *) ;
将一个给定的文件描述符从集合中删除FD_CLR(int ,fd_set*) ;
检查集合中指定的文件描述符是否可以读写FD_ISSET(int ,fd_set* ) 。一会儿 举 例 说 明。
第二, struct timeval 是一个大家常用的 结 构,用来代表 时间值 ,有两个成 员 ,一个是秒数,另一个是毫秒数。


具体解 释 select 的参数:
int maxfdp
是一个整数 值 ,是指集合中所有文件描述符的范 围 ,即所有文件描述符的最大 值 加 1 ,不能 错 !在 Windows 中 这 个参数的 值 无所 谓 ,可以 设 置不正确。
fd_set*readfds
是指向 fd_set 结 构的指 针 , 这 个集合中 应该 包括文件描述符,我 们 是要 监视这 些文件描述符的 读变 化的,即我 们关 心是否可以从 这 些文件中 读 取数据了,如果 这 个集合中有一个文件可 读 , select 就会返回一个大于 0 的 值 ,表示有文件可 读 ,如果没有可 读 的文件, 则 根据 timeout 参数再判断是否超 时 ,若超出 timeout 的 时间 , select 返回 0 ,若 发 生 错误 返回 负值 。可以 传 入 NULL 值 ,表示不 关 心任何文件的 读变 化。
fd_set*writefds
是指向 fd_set 结 构的指 针 , 这 个集合中 应该 包括文件描述符,我 们 是要 监视这 些文件描述符的写 变 化的,即我 们关 心是否可以向 这 些文件中写入数据了,如果 这 个集合中有一个文件可写, select 就会返回一个大于 0 的 值 ,表示有文件可写,如果没有可写的文件, 则 根据 timeout 参数再判断是否超 时 ,若超出 timeout 的 时间 , select 返回 0 ,若 发 生 错误 返回 负值 。可以 传 入 NULL 值 ,表示不 关 心任何文件的写 变 化。
fd_set *errorfds
同上面两个参数的意 图 ,用来 监视 文件 错误 异常。


struct timeval *timeout
是 select 的超 时时间 , 这 个参数至 关 重要,它可以使 select 处 于三 种 状 态 ,

第一,若将 NULL 以形参 传 入,即不 传 入 时间结 构,就是将 select 置于阻塞状 态 ,一定等到 监视 文件描述符集合中某个文件描述符 发 生 变 化 为 止;

第二,若将 时间值设为 0 秒 0 毫秒,就 变 成一个 纯 粹的非阻塞函数,不管文件描述符是否有 变 化,都立刻返回 继续执 行,文件无 变 化返回 0 ,有 变 化返回一个正 值 ;

第三, timeout 的 值 大于 0 , 这 就是等待的超 时时间 ,即 select 在 timeout 时间 内阻塞,超 时时间 之内有事件到来就返回了,否 则 在超 时 后不管怎 样 一定返回,返回 值 同上述。
返回 值 :
负值 : select 错误 正 值 :某些文件可 读 写或出 错 0 :等待超 时 ,没有可 读 写或 错误 的文件
在有了 select 后可以写出像 样 的网 络 程序来! 举 个 简单 的例子,就是从网 络 上接受数据写入一个文件中。
例子:
main()
{
    int sock;
    FILE *fp;
    struct fd_set fds;
    struct timeval timeout={3,0}; //select
等待3 秒,3 秒轮询,要非阻塞就置0
    char buffer[256]={0}; //256
字节的接收缓冲区
    /*
假定已经建立UDP 连接,具体过程不写,简单,当然TCP 也同理,主机ip 和port 都已经给定,要写的文件已经打开
    sock=socket(...);
    bind(...);
    fp=fopen(...); */
    while(1)
   {
        FD_ZERO(&fds); //
每次循环都要清空集合,否则不能检测描述符变化
        FD_SET(sock,&fds); //
添加描述符
        FD_SET(fp,&fds); //
同上
        maxfdp=sock>fp?sock+1:fp+1;    //
描述符最大值加1
        switch(select(maxfdp,&fds,&fds,NULL,&timeout))   //select
使用
        {
            case -1: exit(-1);break; //select
错误,退出程序
            case 0:break; //
再次轮询
            default:
                  if(FD_ISSET(sock,&fds)) //
测试sock 是否可读,即是否网络上有数据
                  {
                        recvfrom(sock,buffer,256,.....);//
接受网络数据
                        if(FD_ISSET(fp,&fds)) //
测试文件是否可写
                            fwrite(fp,buffer...);//
写入文件
                         buffer
清空;
                   }// end if break;
          }// end switch
     }//end while
}//end main
 
linux c
语言 select 函数用法
表头文件


#i nclude<sys/time.h>
#i nclude<sys/types.h>
#i nclude<unistd.h>


定义函数

int select(int n,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout);
函数说明 select() 用来等待文件描述词状态的改变。

参数 n 代表最大的文件描述 词 加 1 ,参数 readfds 、 writefds 和 exceptfds 称 为 描述 词组 ,是用来回 传该 描述 词 的 读 ,写或例外的状况。底下的宏提供了 处 理 这 三 种 描述 词组 的方式 :
FD_CLR(inr fd,fd_set* set)
;用来清除描述 词组 set 中相 关 fd 的位
FD_ISSET(int fd,fd_set *set)
;用来 测试 描述 词组 set 中相 关 fd 的位是否 为 真
FD_SET
( int fd,fd_set*set );用来 设 置描述 词组 set 中相 关 fd 的位
FD_ZERO
( fd_set *set ); 用来清除描述 词组 set 的全部位

(关于fd_set及相关宏的定义见/usr/include/sys/types.h)


参数 timeout 为结 构 timeval ,用来 设 置 select() 的等待 时间 ,其 结 构定 义 如下
struct timeval
{
time_t tv_sec;
time_t tv_usec;
};
返回 值 如果参数 timeout 设为 NULL 则 表示 select ()没有 timeout 。
错误 代 码 执 行成功 则 返回文件描述 词 状 态 已改 变 的个数,如果返回 0 代表在描述 词 状 态 改 变 前已超 过 timeout 时间 ,当有 错误发 生 时则 返回 -1 , 错误 原因存于 errno ,此 时 参数 readfds , writefds , exceptfds 和 timeout 的 值变 成不可 预测 。
EBADF
文件描述 词为 无效的或 该 文件已 关闭
EINTR
此 调 用被信号所中断

 

 

 

...
int sockfd;
fd_set fdR;
struct timeval timeout = ..;
...
for(;;) {
FD_ZERO(&fdR);
FD_SET(sockfd, &fdR);
switch (select(sockfd + 1, &fdR, NULL, &timeout)) {
case -1:
error handled by u;
case 0:
timeout hanled by u;
default:
if (FD_ISSET(sockfd)) {
now u read or recv something;
/* if sockfd is father and
server socket, u can now
accept() */
}
}
}

 

 

补充关于select在异步(非阻塞)connect中的应用:

1.将打开的socket设为非阻塞的,可以用fcntl(socket, F_SETFL, O_NDELAY)完
成(有的系统用FNEDLAY也可).

2.发connect调用,这时返回-1,但是errno被设为EINPROGRESS,意即connect仍旧
在进行还没有完成.

3.将打开的socket设进被监视的可写(注意不是可读)文件集合用select进行监视,
如果可写,用
getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, sizeof(int));
来得到error的值,如果为零,则connect成功.

17. 网络编程2 Hi,大家好!上篇文章我们学习了TCP通信的基本框架,包括如何创建服务端和客户端。本章节我们总结学习网络编程相关的细节知识,也是平时开发中需要注意的知识点。 阅读详情

相关推荐

Linux下基于socket的网络编程(包含多线程和Select机制)

本程序是Linux下基于socket套接字完成的简单网络编程程序,可以接收Tcp、Udp单播、Udp组播消息,并且加入了Select机制和多线程编程,比较简单,适合初学者使用。

Linux网络编程——I/O多路转接(1)之 select

上篇文章中,我们已经知道了I/O的五种模式,包含阻塞、非阻塞、信号驱动、多路转接、异步。本文就多路转接模式进行深入分析,其中介绍了三组转接接口:selectpoll和epoll,支持一次性“等”多个文件描述符,以此将进程或线程“等”的时间进行重叠,便于数据就绪后调用对应的recvfrom()等接口进行数据的拷贝。先来复习一下I/O的多路转接是什么I/O多路转接也叫做I/O多路复用,虽然与阻塞I/O类似,但其核心特点在于,能够同时等待多个文件描述符的就绪状态。

学习日记 1298

从零开始搭建一个高性能电流镜:手把手教你设计Wide-Swing Cascode结构

本文详细解析了Wide-Swing Cascode电流镜的设计原理与实战流程。针对低压高性能模拟电路设计的核心挑战,文章手把手指导如何从理论分析、参数计算到仿真验证,搭建一个兼具高输出阻抗和低输出电压裕度的电流镜结构,并深入探讨了偏置电路生成、性能优化及版图匹配等关键要点。

weixin_29294975的博客 625

Linux学习之网络编程(select)

言之者无罪,闻之者足以戒。 - “诗序” 1、阻塞式I/O 下面看一下实现的逻辑: 2、非阻塞式I/O 下面看一下实现的逻辑: 3、I/O复用(select/epoll) (1)  int  select (int maxfdp, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeo...

键盘上的手艺人 1434

SAP BO系统启用邮件发送功能

目录 背景 维护邮件目标 启用邮件功能 背景 为了将BO报表或BO预警信息发送给特定的收件人,需要启用SAP BO系统的邮件发送功能。 维护邮件目标 1. 登录BO系统的中央管理控制台(CMC): http://<bo server name>:<port>/BOE/CMC 2. 点击“Organize”底下的“Servers”按钮进入BO服务器界面: 3. 点击“Servers List”进入服务器列表界面,右键点击JobServer&lt.

guowenming001的博客 1963

解决vscode无法运行npm命令的问题(cmd可行)

Powershell以及vscode中npm命令使用不了

无痕坚守本心的博客 2749

Linux网络编程:select和epoll多路复用详解

在网络编程中,服务器需要同时处理多个客户端连接。传统的阻塞式IO模型限制了服务器的性能和并发能力。为解决这个问题,Linux提供了IO多路复用技术,其中最常用的是select和epoll机制。本文将详细介绍这两种机制的原理、实现和最佳实践。在服务器开发中,I/O多路复用是实现高并发处理的关键技术。select适合连接数较少、需要跨平台的应用epoll适合大量并发连接、对性能要求高的Linux服务器无论选择哪种方式,良好的资源管理和错误处理都是构建稳定服务器的基石。

永不止息 1014

【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法

相比C文本类编程语言,Simulink图形化编程语言的优势是逻辑思路和数据流清晰了很多,劣势是程序执行的时序不明确,而且各个模块的配置使编程的灵活度下降了不少,在使用习惯上面总感觉有各种限制。本文就是拆解Simulink中最基础的几个编程模块,发扬它的优势,避开劣势。

Mr.Cssust的博客 3850

【Linux网络编程】I/O多路转接之select

我们曾经说过 IO = 等 +数据拷贝。select是多路转接的一种,它只负责等待,可以一次等待多次fd,更为重要的是select本身没有数据拷贝的能力,拷贝要read、write来完成。系统提供select函数来实现多路复用输入/输出模型。关于select接口我们有很多疑问,它怎么做到一次等待多个fd,如果关心fd的读、写、异常,然后又如何通知我们的等。接口学完,我们编写select服务器,进一步掌握它里面各种细节。

fight_p的博客 1552

英飞凌Tricore实战系列导读

笔者结合项目应用经验对Tricore MCU的开发及应用经验进一步总结,成人达己,渡己渡人。

initiallizer的博客 3790

配置某VLAN下ONU的二层互访(隔离)问题(解决OLT二层隔离问题)

问题:OLT的ONU节点之间在同一VLAN下的终端默认隔离,在确实需要互通的场景下如何解决。

symstandsun的博客 4567

Linux网络编程:select函数的用法和原理

select函数用于检测一组socketsocketrecreadrecvreadsocketrecvreadsocketsocketsocketsocketsocketsocketconnectselect()参数说明socketselecttimeval参数的类型都是fd_set,这是一个结构体信息定义如下8intsizeof1UL<<->假设未定义整理一年将一个fd添加到fd_set这个集合中时需要使用FD_SET__FD_SETdounsignedint;;for0;

qq_42896106的博客 660

【Reality Capture 】01:Reality Capture1.5中文版安装教程(附安装包下载)

本文详细介绍了Reality Capture 1.5中文版的安装步骤。首先,下载并解压Reality Capture v1.4.0汉化版安装包,运行EpicInstaller并更改安装路径。接着,启动Epic Games Launcher,登录或注册账号后下载并安装软件。安装完成后,进入主界面并设置中文语言。此外,还提供了中文补丁的拷贝方法,将ui.xml和RealityCapture_CHS.exe文件分别放置到指定目录,并运行RealityCapture_CHS.exe以完成汉化。最后,文章提供了Rea

智慧空间实验室 1749

linux c语言 select函数用法

linux c语言 select函数用法        Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect、accept、recv或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待...

wu694128的博客 228

Microsoft Forms功能深度解析:企业数据收集与协作的智能利器

Microsoft Forms是微软365生态中的在线表单工具,支持问卷调查、测验和投票创建,具备拖拽式界面、多题型设计和实时数据分析功能。其核心价值在于易用性、跨平台兼容性以及与Teams、SharePoint等微软服务的深度集成,满足GDPR/HIPAA等合规要求。提供表单创建、权限管理、自动化流程(通过Power Automate)和审计日志等功能,适用于金融、医疗、教育等多行业场景。虽然存在逻辑分支有限等约束,但通过案例证明能显著提升数据收集效率(达70-85%)。使用时需注意许可证配置(Busin

xueyunshengling的博客 9125

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

linux c语言 select函数用法 - - ITeye技术网站

linux c语言 select函数用法 - - ITeye技术网站 linux c语言 select函数用法 - - ITeye技术网站linux c语言 select函数用法 博客分类:C语言C++CC#LinuxD语言Select在Socket编程中还是比...

108

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Linux网络编程--select()和pselect()函数

函数select()与之前的recv()和send()直接操作文件描述符不同。使用select()函数可以先对需要操作的文件描述符进行查询,查看是否目标文件描述符可以进行读、写或者错误操作,然后当文件描述符满足操作的条件的时候才进行真正的IO操作。函数select()是用一种超时轮循的方式来查看文件的读写错误可操作性。在Linux下,还有一个相似的函数pselect()。函数select()和pselect()用于IO复用,它们监视多个文件描述符的集合,判断是否有符合条件的时间发生。...

木牛的博客 1043

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

linux网络编程之 select 机制的使用

select机制简介: 在传统的网络编程方式中,在使用accept和recv等阻塞函数的时候,会造成应用程序阻塞,进而造成程序响应不及时(比如服务器在等待一个客户端发送数据,那么没有被等待的另一个客户端此时发送给服务器的数据不会被立即处理,造成客户等待)和CPU使用率低(经常等待数据,造成CPU经常没有活干)等等问题。为了解决传统网络编程方式存在的这些问题,linux设计者们提出了IO复用的

做事要专心 2247

【转】linux c语言 select函数用法

linux c语言 select函数用法2009年04月29日 星期三 10:03         Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect、accept、recv或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必

ly21st的专栏 1138

I/O复用----fcntl和select

linux 网络编程总结 linux网络编程中两个重要的高级编程函数:fcntl和select 函数原型如下: 1、int select(int n,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout); 2、 int fcntl(int fd , int cmd); int fcn

非淡泊无以明志,非宁静无以致远 729

epoll函数使用详解 和 select的区别

epoll - I/O event notification facility 在linux的网络编程中,很长的时间都在使用select来做事件触发。在linux新的内核中,有了一种替换它的机制,就是epoll。相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率。因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多。se...

897371388 179

c++ 网络编程(八) LINUX-epoll/windows-IOCP下 socket opoll函数用法 优于select方法的epoll 以及windows下IOCP 解决多进程服务端创...

原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9622548.html 锲子:关于并发服务器中的I/O复用实现方式,前面在网络编程系列四还是五来着????我们讲过select的方式,但select的性能比较低,当连接数量超过几百个的时候就很慢了,并不适合以Web服务器端开发为主流的现代开发环境。因此就有了Linux下的epol...

weixin_30911809的博客 223

[Linux网络编程]TCP/UDP、I/O复用、本地套接字

没写完呢

记忆超差的本人的博客 393

Linux网络编程基础

文章目录Linux网络编程基础命名socketconnect函数listen函数accpet函数close函数描述符引用计数shutdown函数套接字超时SO_REUSEADDR和SO_REUSEPORT套接字选项SO_KEEPALIVE套接字选项SO_LINGER套接字选项select函数描述符就绪条件poll函数I/O模型阻塞式I/O模型非阻塞式I/O模型I/O复用模型信号驱动式I/O模型异步I/O模型各种I/O模型的比较 Linux网络编程基础 命名socket 创建socket时,我们指定了地址族,

qq_36553387的博客 911

网络通信 --> epoll用法

epoll用法   在linux的网络编程中,很长的时间都在使用select来做事件触发。在linux新的内核中,有了一种替换它的机制,就是epoll。 epoll函数 1. 创建epoll的句柄   size表示此内核监听的数目一共有多大,当创建好epoll句柄后,它就是会占用一个fd值,在linux下如果查看/proc/进程id/fd/,是能够看到这个fd的,所以在使用完epol...

weixin_30709809的博客 115
上一篇: linux 网络编程 epoll
下一篇: 我的vimrc
ls1122
博客等级 码龄17年 24粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值