select函数用来检查套接字描述符(sockets descriptors)是否已准备好读/,提供了一种同时检查多个套接字的方法。

Linux中select函数的声明在/usr/include/x86_64-linux-gnu/sys/select.h文件中,Windows下select函数的声明在WinSock2.h文件中,声明如下:

// Linux
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
// Windows
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout);
// macros
FD_SET(int fd, fd_set *set); // Add fd to the set
FD_CLR(int fd, fd_set *set); // Remove fd from the set
FD_ISSET(int fd, fd_set *set); // Return true if fd is in the set
FD_ZERO(fd_set *set); // Clear all entries from the set

不像socket中connect、accept、recv这几个函数属于阻塞方式,而select函数属于非阻塞方式。在使用select函数时,会经常用到四个宏FD_SET(将一个指定的文件描述符加入集合)、FD_CLR(将一个指定的文件描述符从集合中删除)、FD_ISSET(检查一个指定的文件描述符是否在集合中)、FD_ZERO(清空集合)。类型fd_set存放的是一组文件描述符的集合,在Linux系统中,如设备、管道、FIFO等都可通过文件描述符的形式来访问。文件描述符在形式上是一个非负整数,实际上,它是一个索引值。套接字也是文件描述符。

select函数参数介绍:

第一个参数nfds在Linux指的是highest-numbered的文件描述符+1,类型为int。在Windows下,这个参数可以忽略,可以是任意值。

第二个参数readfds是可选的,若不为null,select返回一个大于0的值,表示有文件可读;如果没有可读的文件,则根据timeout参数的值再判断是否超时,若超出timeout的时间,select返回0;若发生错误返回负值。

第三个参数writefds是可选的,若不为null,select返回一个大于0的值,表示有文件可写;如果没有可写的文件,则根据timeout参数的值再判断是否超时,若超出timeout的时间,select返回0;若发生错误返回负值。

第四个参数exceptfds是可选的,若不为null,select返回一个大于0的值,表示有异常发生在文件集合中;如果没有异常发生,则根据timeout参数的值再判断是否超时,若超出timeout的时间,select返回0;若发生错误返回负值。

第五个参数timeout是可选的,若不为null,则用来设置超时时间,则为等待的超时时间;若为null,则将select设置为阻塞状态,直到文件描述符集合中某个文件描述符发生变化时才会返回结果。

返回值:返回-1表示调用select函数时有错误发生,具体的错误在Linux可通过errno输出来查看,在Windows下可通过WSAGetLastError查看;返回0,表示select函数超时;返回正数即调用select函数成功,表示集合中文件描述符的数量,集合也会被修改以显示哪一个文件描述符已准备就绪。

以下为测试代码(funset_socket.cpp):

#include "funset.hpp"
#ifdef _MSC_VER
#include <WinSock2.h>
#include <winsock.h>
#else
#include <sys/select.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#endif
#include <iostream>int test_select_1()
{
#ifdef _MSC_VERfd_set fds;FD_ZERO(&fds);timeval tv;tv.tv_sec = 2;tv.tv_usec = 0;int ret = select(0, &fds, nullptr, nullptr, &tv);if (ret == SOCKET_ERROR) {fprintf(stderr, "fail to select, error: %d\n", WSAGetLastError());return -1;} else if (ret == 0) {fprintf(stderr, "select timeout\n");return -1;} else {fprintf(stdout, "success to select\n");}
#elseconst char* path = "/dev/video0";int fd = open(path, O_RDWR);if (fd == -1) {fprintf(stderr, "fail to open device: %s\n", path);}fd_set fds;FD_ZERO(&fds);FD_SET(fd, &fds);struct timeval tv;tv.tv_sec = 2;tv.tv_usec = 0;int ret = select(fd+1, &fds, nullptr, nullptr, &tv);if (ret == -1) {fprintf(stderr, "fail to select, error: %d, %s\n", errno, strerror(errno));return -1;} else if (ret == 0) {fprintf(stderr, "select timeout\n");return -1;} else {fprintf(stdout, "success to select\n");}close(fd);
#endifreturn 0;
}

在Linux下执行结果如下:

GitHub:https://github.com/fengbingchun/OpenSSL_Test

C语言中select函数简介及使用相关推荐

  1. C语言中select函数的使用

    一般用connect.accept.recv或recvfrom这类函数,程序阻塞,直至该套接字上接受到数据后程序才能继续运行.但是使用select函数可以实现非阻塞方式的程序.它能够监视我们需要监视的 ...

  2. C语言中signal函数简介及使用

    signal.h是C标准函数库中的信号处理部分,定义了程序执行时如何处理不同的信号.信号用作进程间通信,报告异常行为(如除零).用户的一些按键组合(如同时按下Ctrl与C键,产生信号SIGINT).C ...

  3. 关于C语言中printf函数“输出歧视”的问题

    目录 关于C语言中printf函数"输出歧视"的问题 问题描述 探索问题原因 另一种研究方法 问题结论 关于C语言中printf函数"输出歧视"的问题 问题描述 ...

  4. C语言中atoi()函数的用法

    C语言中atoi()函数的用法 一.学习要点: 1.int atoi(const char *str)把参数str所指向的字符串转换为一个整数: 二.代码 #include<stdio.h> ...

  5. r语言中c函数错误,R语言中c()函数与paste()函数的区别说明

    c()函数:将括号中的元素连接起来,并不创建向量 paste()函数:连接括号中的元素 例如 c(1, 2:4),结果为1 2 3 4 paste(1, 2:4),结果为"1 2" ...

  6. C语言中main函数的研究,以及对代码断点调试的研究(王爽老师 汇编语言)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 我们知道作为一个语言本身是不会有诸如从main函数开始运行这样的条件(深层次的说 底层汇编代码不会指定从mian函数开始的这样的条件,程序开始的位 ...

  7. 浅析C语言中strtol()函数与strtoul()函数的用法

    这篇文章主要介绍了浅析C语言中strtol()函数与strtoul()函数的用法,注意其将字符串转换成long型的区别,需要的朋友可以参考下 头文件: ? 1 #include <stdlib. ...

  8. c语言memcopy_C语言中memcpy 函数的用法详解

    C语言中memcpy 函数的用法详解 memcpy(内存拷贝函数) c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址 ...

  9. c语言中memcpy函数_带有示例的C中的memcpy()函数

    c语言中memcpy函数 memcpy()函数 (memcpy() function) memcpy() is a library function, which is declared in the ...

最新文章

  1. 欢迎大家观顾【图灵教育社区】
  2. Android之记录并研究Volley框架中知识点
  3. Android 项目,没有可运行的Module项
  4. 【编译原理】让我们来构建一个简单的解释器(Let’s Build A Simple Interpreter. Part 5.)(python/c/c++版)(笔记)Lexer词法分析程序
  5. java与c++的区别-转
  6. 排序函数(sort()、sorted()、argsort()函数)
  7. python 获取窗口句柄_Python如何自动化哄女朋友
  8. 九章基础算法04:二叉搜索树与哈希表
  9. 番茄是水果还是蔬菜这事儿,居然闹到了最高法院?!
  10. python文本筛选html,从html页面的列表元素中筛选数据
  11. java 求两点的角度_计算两点之间的角度 – java
  12. 【小程序实战系列】电商平台源码及功能实现
  13. 前端工作中碰到的一些小问题总结
  14. 在win7上安装AutoCAD2006
  15. Java 回调函数Callback
  16. QQ聊天机器人--基于酷Q写的插件
  17. 安卓的app在所有应用商店上架方法整理
  18. 计算机键盘指示灯不亮也不启动不了机,电脑开机时滴滴响 开不了机,显示器显示无信号,键盘灯不亮...
  19. 创客学院9天C语言一
  20. linux越狱80x24,用Cydia Impactor 免越狱安装未签名APP方法[日常] | 贝贝吧

热门文章

  1. 将数据库数据导入Excel表格
  2. 下列不是C语言字符型常,以下选项中,()是不正确的C语言字符型常量。
  3. Mall of America (美国购物中心 - 美国商城)
  4. 电脑为什么搜索不到蓝牙耳机
  5. 苹果CMS V10详细搭建教程
  6. java oncreate_Android(java)学习笔记112:Activity中的onCreate()方法分析
  7. Python办公自动化之三,操作PDF
  8. 阿里云重磅发布业务中台产品 BizWorks,中台发展进入下一个阶段
  9. 词集模型、词袋模型、词向量模型
  10. Python打开常用文件方法