Unix 网络编程学习笔记--第6章 I/O 复用: select 和poll 函数

I/O 复用(I/O multiplexing) (select/poll)

内核一旦发现进程指定的一个或多个I/O 条件就绪(输入已准备好被读取,或者描述字已经能承接更多的输出),它就通知进程。

#include <sys/select.h>
#include <sys/time.h>
int select(int maxfdp1, fd_set *readset, fd_set* writeset,
 fd_set* exceptset, const struct timeval* timeout);

中间三个指针参数 readset,writeset, exceptset 指定我们要让内核测试读、写和异常条件的描述字,并且,这三个参数都是值-结果参数。
maxfdp1 参数指定待测试的描述字个数,它的值是待测试的最大描述字+1。
该函数的返回值表示所有描述字集的已就绪的总位数。如果在任何描述字就绪之前定时时间到,那么返回0.返回-1表示出错。

TCPv1 第89页说明,这些ping测量所用的是长度为84字节的IP数据报。ping程序是测量RTT的一个简单方法。

close 函数有两个限制,可以使用shutdown来避免。

  1. close 把描述字的引用计数减1,仅在该计数变为0时才关闭套接口。使用shutdown 可以不管引用计数就激发TCP的正常连接终止。
  2. close 终止数据传送的两个方向:读和写。
#include<sys/socket.h>
int shutdown(int sockfd, int howto);

一般而说,为提升性能而引入缓冲机制增加了网络应用程序的复杂性。用fgets读取输入,转而使得已可用的文本输入行被读入到stdio 所用的缓冲区。然而fgets 只返回其中的第一行,其余输入行仍在stdio缓冲区中。 select 不知道stdio 使用了缓冲区,它只是从read 系统调用的角度指出是否有数据可读。因此,stdio和select 混合使用非常容易犯错误。

poll函数
#include<poll.h>
int poll(struct pollfd *fdarray, unsigned long nfds, int timeout);
// 返回,就绪描述字的个数,0--超时,-1--出错

timeout 参数指定poll 函数返回前等待多长时间。它是一个指定应等待的毫秒数的正值。

struct pollfd{
    int fd; //descriptor to check
    short events; // events of interest on fd
    short revents; // events that occurred on fd 
}

要测试的条件由events 成员指定,函数在相应的revents 成员中返回该描述字的状态。
poll 识别三类数据。

  1. 普通(normal) 所有正规的TCP 和UDP 数据都被认为是普通数据
  2. 优先级带(priority band) TCP 的带外数据被认为是优先级带数据
  3. 高优先级(high priority)

猜你喜欢

转载自blog.csdn.net/lilele12211104/article/details/79709834