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 调用方等待指定的毫秒数后返回
  • 31
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值