I/O多路转接之select

避坑指南:AUTOSAR FlashDriver操作DFlash模拟EEPROM时,你最容易忽略的5个细节 本文深入探讨了AUTOSAR FlashDriver在DFlash模拟EEPROM操作中最容易被忽视的五大细节问题,包括地址合法性检查、操作时序控制、并发访问冲突、电源稳定性管理和寿命管理。通过实际项目案例和工程化解决方案,帮助开发者避免常见陷阱,提升汽车电子控制单元(ECU)的可靠性和稳定性。 阅读详情
    I/O多路转接之select
  作用:是用来让我们的程序监视多个文件句柄的状态变化的。程序会停在select这里等待,直到被监视的文件句柄有一个或多个发生了状态改变。
  
  函数原型:

     中间的三个参数readset、writeset和exceptset指定我们要让内核测试读、写和异常条件的描述字。如果对某一个的条件不感兴趣,就可以把它设为空指针。struct fd_set可以理解为一个集合,这个集合中存放的是文件描述符,可通过以下四个宏进行设置:

          void FD_ZERO(fd_set *fdset);           //清空集合

          void FD_SET(int fd, fd_set *fdset);   //将一个给定的文件描述符加入集合之中

          void FD_CLR(int fd, fd_set *fdset);   //将一个给定的文件描述符从集合中删除

          int FD_ISSET(int fd, fd_set *fdset);   // 检查集合中指定的文件描述符是否可以读写 

  fd_set结构体是文件描述符集,该结构体实际上是一个整型数组,数组中的每个元素的每一位标记一个文件描述符。fd_set能容纳的文件描述符 数量由FD_SETSIZE指定,一般情况下,FD_SETSIZE等  于1024,这就限制了select能同时处理的文件描述符的总量。

timeout告知内核等待所指定描述字中的任何一个就绪可花多少时间。其timeval结构用于指定这段时间的秒数和微秒数。

         struct timeval{

                   long tv_sec;   //seconds

                   long tv_usec;  //microseconds

       };

这个参数有三种可能:

  1)永远等待下去:仅在有一个描述字准备好I/O时才返回。为此,把该参数设置为空指针NULL。

  2)等待一段固定时间:在有一个描述字准备好I/O时返回,但是不超过由该参数所指向的timeval结构中指定的秒数和微秒数。

  3)根本不等待:检查描述字后立即返回,这称为轮询。为此,该参数必须指向一个timeval结构,而且其中的定时器值必须为0。

函数返回值:
 1、执行成功则返回文件描述词状态已改变的个数;
 2、如果返回0代表在描述词状态改变前已超过timeout时间,没有返回;
 3、当有错误发生时则返回-1,错误原因存于errno,此时参数readfds,writefds,exceptfds和 timeout的值变成不可预测。错误值可能为:
EBADF 文件描述词为无效的或该文件已关闭
EINTR 此调用被信号所中断 EINVAL 参数n 为负值。
ENOMEM 核心内存不足

说明:

   1、select只负责等待IO,不负责对IO进行操作,由recv/send等函数进行

   2、select一共有两次系统调用:1)select系统调用 2)recvfrom系统调用

select的优点:
  select模型是Windows sockets中最常见的I/O模型,它利用select实现I/O管理,通过对select函数的调用,应用程序可以判断套接字是否存在数据、能否向该套接字写入数据。
  如:在调用recv函数之前,先调用select函数,如果系统中没有可读的数据,那么select函数就会阻塞在这里。当系统中存在可读和可写的数据时,select函数返回,就可以调用recv函数接受数据了。
  可以看出select模型,需要两次调用函数。第一次调用select函数和第二次调用socket API。使用该模式的1好处是:可以等待多个套接字。

select的缺点:
  1、最大并发数限制:使用32个整数的32位,即32*32=1024来标示fd;
  2、效率低,每次都会线性的扫描整个fd_set,集合越大速度越慢
  3、每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大。


使用select编写网络服务器
代码:
/**************************************************************************
    >file name:my_select.c
    >author:Comedly
    >create time:2016-8-7
**************************************************************************/

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/select.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>

int fds[64];
const int fds_nums = sizeof(fds)/sizeof(fds[0]);

static int startup(const char* ip,int port)
{
    int sock = socket(AF_INET,SOCK_STREAM,0);
    if(sock < 0)
    {
        perror("socket()");
        exit(2);
    }

    int opt = 1;
    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(port);
    local.sin_addr.s_addr = inet_addr(ip);

    if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0)
    {
        perror("bind()");
        exit(3);
    }

    if(listen(sock,5) < 0)
    {
        perror("listen()");
        exit(4);
    }
    return sock;
}

static void usage(const char *proc)
{
    printf("%s [ip] [port]\n",proc);
}

int main(int argc,char* argv[])
{
    if(argc != 3)
    {
        usage(argv[0]);
        exit(1);
    }

    int listen_sock = startup(argv[1],atoi(argv[2]));
    fd_set rset;
    int i = 0;
    FD_ZERO(&rset);
    FD_SET(listen_sock,&rset);
    //initial fds
    for(;i < fds_nums;i++)
    {
        fds[i] = -1;
    }
    fds[0] = listen_sock;
    int done = 0;
    while(!done)
    {
        int max_fd = -1;
        for(i = 0;i < fds_nums;i++)
        {
            if(fds[i]>0)
            {
                FD_SET(fds[i],&rset);
                max_fd = max_fd < fds[i]?fds[i]:max_fd;
            }
        }
        switch(select(max_fd+1,&rset,NULL,NULL,NULL))
        {
            case 0:
                printf("time out...\n");
                break;
            case -1:
                perror("select()");
                break;
            default:
                for(i = 0;i < fds_nums;i++)
                {
                    if(i==0 && FD_ISSET(listen_sock,&rset))
                    {
                        //printf("there\n");
                        struct sockaddr_in peer;
                        socklen_t len = sizeof(peer);
                        int newfd = accept(listen_sock,(struct sockaddr*)&peer,&len);
                        if(newfd > 0)
                        {
                            printf("get a new client$ socket->%s:%d\n",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port));
                        }
                        int j = 0;
                        for(j;j<fds_nums;j++)
                        {
                            if(fds[j] == -1)
                            {
                                fds[j] = newfd;
                                break;
                            }
                        }
                        if(j == fds_nums)
                        {
                            close(newfd);
                        }
                    }
                    else//normal accept_fd
                    {
                        if(FD_ISSET(fds[i],&rset))
                        {
                            char buf[1024];
                            memset(buf,'\0',sizeof(buf));
                            ssize_t _s = read(fds[i],buf,sizeof(buf)-1);
                            if(_s > 0)
                            {
                                buf[_s-1] = '\0';
                                printf("client$ %s\n",buf);
                            }
                            else if(_s == 0)
                            {
                                printf("%d is read done......\n",fds[i]);
                                write(fds[i],"mn",2);
                                sleep(10);
                                close(fds[i]);
                                fds[i] = -1;
                            }
                            else
                            {
                                perror("read()");
                            }
                        }

                    }
                }
                break;
        }
    }
    return 0;
}
运行结果:





新华硕笔记本ubuntu18.04双系统安装之后,wifi没有显示无法链接wifi 本来我以为跟简单安装一个wifi网卡的驱动就可以解决的问题,没想到花了我一早上的时候解决… 惭愧。 另外,本来是没打算写这篇博客的,但是我在搜索解决这个问题的过程中, 发现多人提出的解决方案跟我的都不一样,甚至我的解决方案都没有搜到相应的答案,还是只能靠自己啊。。 言归正传,还是说说怎么正确的安装wifi驱动吧! 1. wifi没有正确安装、或没有正确配置的表现 我的电脑现象: 有wifi图标, wifi设置上显示unaviable,无法搜索到任何wifi; 还有其他类似的表现,大家可以看看其他朋友的提 阅读详情

相关推荐

保姆级教程:Java调用海康SDK实现录像回放与倍速播放(附完整代码)

本文详细介绍了如何使用Java调用海康SDK实现录像回放与倍速播放功能,包括开发环境配置、设备连接、流媒体处理、倍速播放实现及性能优化等关键步骤。通过完整的代码示例和实战经验,帮助开发者快速构建智能录像回放系统,提升开发效率。

weixin_29285605的博客 357

I/O 多路转接select、poll

设最大文件描述符是。

jingfeng514的博客 1377

Altium Designer操作技巧(12)——如何进行邮票孔拼版?

【摘要】本文详细介绍了PCB设计中邮票孔拼板的全流程操作方法。首先解释了邮票孔拼板的定义、核心目的(提高贴片效率、方便生产)和适用场景(异形板、V-CUT无法实现的情况)。重点阐述了关键设计参数,包括孔径、数量、间隙等规范要求,并提供了两种具体操作方案:传统复制粘贴法和新版阵列放置法。文章通过图文详细演示了从PCB复制、邮票孔添加、板框定义到定位孔和Mark点设置的完整步骤,最后强调了对称性、非金属化孔等设计要点,以及需要与板厂确认工艺参数等注意事项。

u012526819的博客 1676

【Linux网络】深入解析I/O多路转接 - Select

系统提供select函数来实现多路复用输入/输出模型select系统调用是用来让我们的程序监视多个文件描述符的状态变化的;程序会停在select这里等待,直到被监视的文件描述符有一个或多个发生了状态改变;定位:只负责进行等,不进行拷贝!作用:为了等待多个fd,等待fd上面的新事件就绪,通知程序员,事件已经就绪,可以进行IO拷贝了!本篇博文对【Linux网络】深入解析I/O多路转接 - Select做了一个较为详细的介绍,不知道对你有没有帮助呢觉得博主写得还不错的三连支持下吧!会继续努力的~

2301_77954967的博客 1549

V-rep机器人仿真(Win10):UR5+RG2+Kinect+YOLOV3+DDPG+Pytorch(第四部分:YOLOV3图像识别)

这是一个V-rep机器人仿真实验,较为简单,适合初学者在入门图像识别、机器学习、机器人学的内容时进行学习与训练。 实验涉及的内容有:V-rep机器人仿真,YOLOV3图像识别,强化学习DDPG,UR5机械臂及RG2机械手,Kinect摄像头。 使用环境:Win10,Pytorch0.4,V-rep 整个实验一共由多篇文章组成,本文是第四部分。 第四部分:YOLOV3图像识别 文章目录第四部分:YO...

weixin_42158966的博客 5837

5.1 滑模控制(SMC)及其改进

本文系统阐述了滑模控制(SMC)的基本原理及其在永磁同步电机(PMSM)控制系统中的应用。首先介绍了滑模控制的核心思想,包括滑模面设计和不连续控制律,其强鲁棒性使其在电机控制领域得到广泛应用。其次分析了SMC在PMSM速度控制器和无位置传感器观测器中的具体实现方案。重点探讨了SMC固有的抖振问题,详细比较了边界层法、高阶滑模和自适应方法等多种改进策略的优缺点。最后指出改进SMC的研究趋势是多种策略的融合应用,如自适应高阶滑模等,以在保持鲁棒性的同时有效抑制抖振。

技术工作者 1448

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

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

fight_p的博客 1552

NRF52832调试方法1——HardFault_Handler问题定位

一、遇到问题 keil debug模式下,直接点击全速运行(Run)发现程序卡死,点击stop按钮后,停到了HardFault_Handler位置,如下图所示。 此时使用navigate backwards(蓝色左箭头)是无效的,找不到程序卡在哪里。 二、解决办法 此时首先观察register窗口 若Stack为MSP,则复制R13(SP)的值到memory观察窗的地址搜索栏。每一行显示连续的28个地址上的存储信息,每个地址上存有一个字节。 从第21个位置起的连续四个字节是LR的值,

小梁的博客 3650

I/O多路转接 —— select, poll

当我们借助telnet工具向select服务器发起连接请求后,select函数就会立马检测到监听套接字的读事件就绪,此时select函数便会成功返回,并将我们设置的提示语句进行打印输出,因为当前程序并没有对就绪事件进行处理,此后每次select函数一调用就会检测到读事件就绪并成功返回,因此会看到屏幕不断打印输出提示语句。此时如果select监视的文件描述符上有事件就绪,那么select函数的返回值就是大于0的,如果select监视的文件描述符上没有事件就绪,那么select的返回值就是等于0的。

m0_73634434的博客 1087

AI Agent智能体在Android开发中的应用

本文探讨了AIAgent(智能代理体)在Android开发中的应用,涵盖技术原理、实践案例与未来趋势。AIAgent通过机器学习、自然语言处理等技术实现代码生成、测试自动化及性能优化,显著提升开发效率。例如,强化学习模型可优化APP响应时间(公式:$\text{响应时间}=f(\text{负载},\text{资源})$),自动化测试覆盖率提升至95%。

郑伟强dev的专栏 124

【深度学习新浪潮】Token经济学深度解析:从AI“新智元”梗到产业核心,研究成果+标杆产品全拆解

在正式深入研究和产品分析前,必须先破除概念误区:行业内常说的Token经济学,并非单一概念,而是分为AI词元Token经济学和Web3通证Token经济学两大核心分支,二者底层逻辑、应用场景天差地别,也是大众最容易混淆的点。Token是AI时代的新大宗商品:黄仁勋将Token类比为工业时代的电力、石油,是AI时代的核心生产资料与基础计价单位,不再是单纯的技术单元,而是具备标准化、可计量、可交易、可分层的数字商品,其价值由算力消耗、推理效率、实际应用价值共同决定,而非虚拟炒作。Token五层定价模型。

专注:太空算力、AI infra、异构调度、大模型成本工程 685

I/O多路转接——select,poll,epoll

本文介绍了几种不同的多路转接模型,详细谈了一下epoll的工作模式

better_wei的博客 1120

boost::circular_buffer缓行缓冲区

1、circular_buffer实现了一个环形缓冲区,空间大小是固定的,当到达容器末尾时,将自动利用容器另一端的位置空间。 2、当程序需要容纳大量的元素,但多数情况下仅保存较少数量元素时可以使用circular_buffer_space_optimized,他可以有效的减少内存的占用,提高程序的运行效率。 3、主要接口: 4、实现一个生产者---消费者模式示例: #inc...

小米的修行之路 791

【Linux】I/O 多路转接:select & epoll 技术剖析

本文详细介绍了 Linux 下的 I/O 多路复用技术,包括 select、poll 和 epoll 的原理、优缺点及使用场景。select 和 poll 适用于少量连接,而 epoll 在处理大量并发连接时表现出色,文章通过示例代码展示了如何使用这些技术实现服务器程序,强调了根据实际需求选择合适的 I/O 模型的重要性。

You build it, you run it 3868

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

[Linux]——I/O多路转接select技术

浅析I/O多路转接select技术 在谈I/O多路转接技术之前,我们先来谈谈什么是I/O。I/O是input和ouput的缩写,即输入输出端口,每个设备都有自己的输出输入地址,用来处理自己的输入输出信息。 I/O的五种工作模式 首先我们简单介绍一下I/O的五种工作模式,看看不同的I/O方式是如何进行工作的: 阻塞I/O模型:应用程序调用一个I/O函数,导致应用程序阻塞,此应用程序会一直等待内核将...

lucky52529的博客 1212

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

I/O多路转接之select、poll、epoll详解

select是一个系统调用,用来进行I/O多路转接select可以让程序同时监视多个文件描述符上的事件是否就绪当监视的多个文件描述符中有一个或多个事件就绪时,select才会成功返回并将对应的文件描述符就绪的事件告知调用者。

大学生一枚 1070

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

详解I/O多路转接之select

什么是多路转接IO 对大量的描述符进行I/O事件监控—可以告诉进程现在有哪些描述符就绪了,然后进行就可以只针对就绪了的描述符进行响应操作,避免对没有就绪的I/O操作所导致的效率降低和流程阻塞。 IO事件:可读事件/可写事件/异常事件 I/O多路转接模型之select select介绍 系统提供select函数来实现多路复用输入/输出模型. select系统调用是用来让我们的程序监视多个文件描述符的状态变化的; 程序会停在select这里等待,直到被监视的文件描述符有一个或多个发生了状态改变 操作流程

海盗船长y的博客 1302

【Linux网络编程】第二十弹---熟练I/O多路转接:深入解析select机制与实战

I/O 多路转接之 select:初识 select,select 函数原型,测试timeout,处理事件(三个版本),补充select的理解,select 的特点,select 缺点;完整代码:SelectServer.hpp,Main.cc~~~

小林熬夜学习编程的博客 1712

I/O的多路转接: select

1. 概念:     I/O多路转接技术, 是先构造一张有关描述符的列表, 然后调用一个函数, 直到这些描述符中的一个已准备好进行I/O时, 该函数才返回. 在返回时, 它告诉进程哪些描述符已经准备好可以进行I/O.    在Linux下poll, pselect, select这三个函数都可以执行I/O多路转接操作, 今天我们主要说select函数. 2. select函数:

代威涛的主页 1761

【Linux网络编程】多路转接I/O(一)select,poll

二者对比特性SelectPoll最大 FD 数受限(FD_SETSIZE)无限制性能(FD 量大时)O(n) 扫描O(n) 扫描事件类型仅读/写/异常更丰富(POLLRDNORM 等)平台支持跨平台Linux 专用FD 重用每次需重置 fd_set可复用 pollfd 数组Select:FD 数量少(<1024),需跨平台Poll:FD 数量多,仅需支持 Linux注意:两种模型都采用水平触发(LT)模式,即只要 FD 处于就绪状态,每次调用都会返回该 FD。

2401_82677021的博客 1214

【Linux网络#19】:深入理解select多路转接:传统I/O复用的基石

📃个人主页:island1314🔥个人专栏:Linux—登神长阶。

island1314的博客 1895

I/O多路转接之 select 与 poll

在Linux系统中,I/O多路转接是一种重要的I/O模型,它能够同时等待多个文件描述符的就绪状态,同时处理多个客户端的请求而不创建多线程,提高程序的效率。本文将重点介绍I/O多路转接中的select和poll。

weixin_73567058的博客 1351

I/O多路转接——select、poll、epoll

​ epoll有三个相关的系统调用,分别是epoll_create、epoll_ctl和epoll_wait。

qq_55317476的博客 1726

I/O多路转接之select/poll/epoll

虽然当前的select服务器是一个单进程的服务器,但它却可以同时为多个客户端提供服务,根本原因就是因为select函数调用后会告知select服务器是哪个客户端对应的连接事件就绪了,此时select服务器就可以读取对应客户端发来的数据,读取完后又会调用select函数等待某个客户端连接的读事件就绪。此时如果select监视的文件描述符上有事件就绪,那么select函数的返回值就是大于0的,如果select监视的文件描述符上没有事件就绪,那么select的返回值就是等于0的。

2303_77100822的博客 1321

I/O多路转接之select和非阻塞IO

I/O多路转接之select和非阻塞IO

Dingyuan0的博客 776

【探索Linux】P.47(高级IO —— I/O多路转接之 select)

本文全面介绍了select函数,包括其简介、函数原型及参数说明(特别是timeout的取值和相关结构体fd_set、timeval)、执行过程(从准备阶段到处理就绪的文件描述符)、优缺点以及使用示例。

Yawesh的博客 1315
上一篇: TCP(传输控制协议)之端口分类
下一篇: I/O多路转接之epoll
Comedly
博客等级 码龄10年 17粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值