(二)TCP客户端/服务器通信------select函数

(一)select函数

该函数允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经历一段指定的时间后才唤醒它。也就是说,我们调用select告知内核对哪些描述符(就读、写或异常条件)感兴趣以及等待多长时间。我们感兴趣的描述符不局限于套接字,任何描述符都可以使用select来测试。

(1)参数:

1. timeout:它告知内核等待所指定描述符中的任何一个就绪可花的最长时间。


    1)永远等下去:仅在有一个描述符准备好I/O才返回。空指针。

    2)等待一段固定时间:在固定时长内有准备好的I/O返回,或到达固定时长时返回。

    3)根本不等待:论询。设置为0.

前两种情形的等待通常会被进程在等待期间捕获的信号中断,并从信号处理函数返回。


2. readset、writeset和exceptset:指定我们要让内核测试读、写和异常条件的描述符。

select使用描述符集,通常是一个整数数组,其中每个整数中的每一位对应一个描述符。举例来说,假设使用32位整数,那么该数组的第一个元素对应于描述符0-31,第二个元素对应于描述符32-63位,以此类推。所有这些实现细节都与应用程序无关,它们隐藏在名为fd_set的数据类型和以下四个宏中:

描述符集的初始化非常重要,因为作为自动变量分配的一个描述符集如果没有初始化,那么可能发生不可预期的结果。

select函数修改由指针readset、writeset和exceptset所指向的描述符,因而这三个参数都是值-结果参数。调用该函数时,我们指定所关心的描述符的值,该函数返回时,结果将指示哪写描述符已就绪。该函数返回后,我们用FD_ISSET宏来测试fd_set数据类型中的描述符。描述符集内任何与未就绪描述符对应的位返回时均清0.为此,每次重新调用select函数时,我们都得再次把所有描述符集内所关心的位均置位1.


3.    maxfdp1:指定待测试的最大描述符,它的值是待测试的最大描述符加1

maxfdp1参数迫使我们计算出所关心的最大描述符并告知内核该值。存在这个参数以及就算其值的额外负担纯粹是为了效率原因。

(2)返回:返回值表示跨所有描述符集的已就绪的总位数。

如果在任何描述符就绪之前定时器到时,那么返回0.返回1表示出错(这个可能发生的,譬如本函数被一个所捕获的信号中断)。


(3)描述符就绪条件

(二)shutdown函数

在批量数据传输中,标准输入中的EOF并不意味着我们同时也完成了从套接字的读入:可能仍有请求在去服务器的路上,或者仍有应答在返回客户的路上。

我们需要的是一种关闭TCP连接其中一半的方法。也就是说,我们想给服务器发送一个FIN,告诉它我们已经完成了数据发送,但是仍然保持套接字描述符打开以便读取。这就需要shutdown函数完成。


(三)pselect函数

pselect函数是select函数的升级版。POSIX定义的pselect函数把时间精度升级到纳米级别,并采用一个指向信号集的指针作为它的一个新参数。当有信号量需要捕捉时,该参数能够让我们避免竞争条件。

pselect相对于通常的select有两个变化:

(1)pselect使用timespec结构,而不使用timeval结构。


(2)pselect函数增加了第六个参数:一个指向信号掩码的指针。该参数允许程序先禁止递交某些信号,再测试由这些当前被禁止信号的信号处理函数设置的全局变量,然后调用pselect,告诉它重新设置信号掩码。



猜你喜欢

转载自blog.csdn.net/damage233/article/details/81014796