信号驱动式I/O是指进程预先告知内核,使得当某个描述符发生某事时,内核使用信号通知相关进程。

 

 

 

套接字的信号驱动式I/O

针对一个套接字使用信号驱动式I/O(SIGIO)要求进程执行以下3个步骤:

1.建立SIGIO信号的信号处理函数

2.设置该套接字的属主,通常使用fcntl的F_SETOWN命令设置

3.开启该套接字的信号驱动式I/O,通常通过使用fcntl的F_SETFL命令打开O_ASYNC标志完成

 

 

 

对于UDP套接字的SIGIO信号

在UDP上使用信号驱动式I/O是简单得。SIGIO信号在发生以下事件时产生:

1.数据报到达套接字

2.套接字上发生异步错误

因此当捕获对于某个UDP套接字的SIGIO信号时,我们调用recvfrom读入到达的数据报或者获取发生的异步错误。

使用SIGIO的UDP回射服务器程序

下面是构建一个UDP服务器的两种方式,我们的程序使用的右面的方式

UNP学习笔记(第二十五章 信号驱动式I/O)

 

1.全局声明

SIGIO信号处理函数把到达的数据放入一个队列。该队列是一个DG数据数组,我们把它作为一个环形缓冲区处理

每个DG结构包括指向所收取数据报的一个指针、该数据包的长度、指向含有客户协议地址的某个套接字地址结构的一个指针、该协议地址的大小。

iget是主循环将处理的下一个数组元素的下标,iput是信号处理函数将存放到下一个数组元素的下标,nqueue是队列中共主循环处理的数据报的总数

 1 #include    "unp.h"
 2 
 3 static int        sockfd;
 4 
 5 #define    QSIZE       8        /* size of input queue */
 6 #define    MAXDG    4096        /* max datagram size */
 7 
 8 typedef struct {
 9   void        *dg_data;        /* ptr to actual datagram */
10   size_t    dg_len;            /* length of datagram */
11   struct sockaddr  *dg_sa;    /* ptr to sockaddr{} w/client's address */
12   socklen_t    dg_salen;        /* length of sockaddr{} */
13 } DG;
14 static DG    dg[QSIZE];            /* queue of datagrams to process */
15 static long    cntread[QSIZE+1];    /* diagnostic counter */
16 
17 static int    iget;        /* next one for main loop to process */
18 static int    iput;        /* next one for signal handler to read into */
19 static int    nqueue;        /* # on queue for main loop to process */
20 static socklen_t clilen;/* max length of sockaddr{} */
21 
22 static void    sig_io(int);
23 static void    sig_hup(int);
View Code

相关文章: