Linux编程4.12 网络编程-高级编程

  • 前面介绍的函数如recv、send、read和write等函数都是阻塞性函数,若资源没有准备好,则调用该函数的进程进入阻塞状态,下面是两种I/O多路复用的解决方案。
  • fcntl函数实现(将套字设置为非阻塞方式)
  • select函数实现
  • poll函数实现

1、 fcntl函数实现(非阻塞方式)

在这里插入图片描述

#include <unistd.h>
#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */ );
功能:对打开的文件描述符fd执行描述的操作,操作由cmd决定。

2、I/O多路转换select函数

#include <sys/select.h>
 int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

void FD_CLR(int fd, fd_set *set);
int  FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);
int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout,const sigset_t *sigmask);

1)、参数

  • maxfdp1:最大fd加1(max fd plus 1),在三个描述符集中找出最高描述符编号值,然后加1,这就是第第一参数值。(即要监听的所有套接子中,最大的+1)
  • readfds、writefds和exceptfds:是指向描述符集的指针。这三个描述符集说明了我们关心的可读,可写或处于异常条件的各个描述符。每个描述符集存放在一个fd_set数据类型中。

2)、select函数根据希望进行的文件操作对文件描述符进行分类处理,这里,对文件描述符的处理主要 设计4个宏函数

  • FD_ZERO(fd_set *set) 清除一个文件描述符集;
  • FD_SET(int fd, fd_set *set) 将一个文件描述符加入文件描述符集中
  • FD_CLR(int fd, fd_set *set) 将一个文件描述符从文件描述符中清除
  • FD_ISSET(int fd,fd_set *set) 测试该集中的一个给定位是否有变化(返回0表示,该fd没有准备好,返回1表示该fd准备好了)

3)、在使用select函数之前,首先使用FD_ZERO和FD_SET来初始化文件描述符集,并使用select函数时,可循环使用FD_ISSET测试描述符集,在执行完成对应的文件描述符后,使用FD_CLR来清除描述符集。

4)、总体描述
①select IO多路复用,可以同时监听多个文件描述符,若至少一个文件描述符状态变为“准备”状态,则select被唤醒,
②select函数中,若timeval时间到,则被唤醒,timeval若为NULL,则没有时间,永久阻塞,等待套接字准备状态。
③其它情况下,select函数,保持阻塞,等待被唤醒
④select函数,在监听套按字的时候,根据传参的fd_set判断,需要监听哪些套接字,比如第n位为1,则n会被监听,若m位为0,则m不监听
⑤被唤醒后,根据返回值可以判断是否套接字“准备”状态唤醒,确定是套接字唤醒后,如何判断是哪个套接字,多少个套接字造成的唤醒?

  • 返回值大于0,返回结果为多少个套接字造成的唤醒
  • 哪个造成的唤醒,使用FD_ISSET来判断。
    3、poll函数
    poll的实现和select非常相似,只是描述fd集合的方式不同。
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);

struct pollfd {
   int fd;           /*文件描述符*/
   short events;     /*监控的事件*/
   short revents;    /*返回的事件*/
};

参数:

  • fds:struct pollfd类型的数组, 存储了待检测的文件描述符,struct pollfd有三个成员:
  • fd:委托内核检测的文件描述符 events:委托内核检测的fd事件(输入、输出、错误),每一个事件有多个取值
  • revents:这是一个传出参数,数据由内核写入,存储内核检测之后的结果 nfds:描述的是数组 fds 的大小 timeout:
  • 指定poll函数的阻塞时长
    • -1:一直阻塞,直到检测的集合中有就绪的IO事件,然后解除阻塞函数返回
    • 0:不阻塞,不管检测集合中有没有已就绪的IO事件,函数马上返回
    • 大于0:表示 poll 调用方等待指定的毫秒数后返回

相关推荐

  1. linux网络----UDP编程

    2024-03-21 07:34:03       36 阅读
  2. Linux网络编程

    2024-03-21 07:34:03       21 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-21 07:34:03       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-21 07:34:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-21 07:34:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-21 07:34:03       20 阅读

热门阅读

  1. 【面试自测】Spring

    2024-03-21 07:34:03       21 阅读
  2. python實現excel轉txt代碼

    2024-03-21 07:34:03       21 阅读
  3. SpringMVC

    SpringMVC

    2024-03-21 07:34:03      17 阅读
  4. 无人机拦截

    2024-03-21 07:34:03       20 阅读
  5. kafka 集群

    2024-03-21 07:34:03       19 阅读
  6. Kafka

    2024-03-21 07:34:03       20 阅读
  7. 【 React 】 在React项目中是如何使用Redux的?

    2024-03-21 07:34:03       21 阅读
  8. React——props children (插槽平替)

    2024-03-21 07:34:03       19 阅读
  9. 全量知识系统 概要设计(SmartChat回复)

    2024-03-21 07:34:03       21 阅读
  10. webRtc麦克风摄像头检测

    2024-03-21 07:34:03       18 阅读