UNP学习笔记(第十六章 非阻塞I/O)

来源:互联网 发布:算法第四版答案 编辑:程序博客网 时间:2024/05/02 09:53
套接字的默认状态时阻塞的

可能阻塞的套接字调用可分为以下4类:

1.输入操作,包括read、readv、recv、recvfrom和recvmsg。

2.输入操作,包括write、writev、send、sendto和sendmsg。

3.接受外来连接,即accept函数。

4.发起外出连接,即用于TCP的connect函数(该函数一直要等到客户收到对于自己的SYN的ACK为止才返回)

 

 

 

 

非阻塞connect

当在一个非阻塞的TCP套接字上调用connect时,connect将立即返回一个EINPROGRESS错误,不过已经发起的TCP三路握手继续执行。

非阻塞的connect有三个用途:

1.完成一个connect至少要花一个RTT时间,这段时间内也许我们想要执行的其他处理工作可执行

2.我们可以使用这个技术同时建立多个连接。这个用途已随着Web浏览器变得流行起来

3.既然使用select等待连接的建立,我们可以给select指定一个时间限制,使得我们能够缩短connect的超时

   应用程序有时想要一个更短的超时时间,实现方法之一是使用非阻塞connect

 

 

 

非阻塞connect:时间获取客户程序

下面给出connect_nonb函数执行一个非阻塞connect,其中第四个参数是等待连接完成的秒数

 1 #include    "unp.h" 2  3 int 4 connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec) 5 { 6     int                flags, n, error; 7     socklen_t        len; 8     fd_set            rset, wset; 9     struct timeval    tval;10 11     flags = Fcntl(sockfd, F_GETFL, 0);12     Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);13 14     error = 0;15     if ( (n = connect(sockfd, saptr, salen)) < 0)16         if (errno != EINPROGRESS)17             return(-1);18 19     /* Do whatever we want while the connect is taking place. */20 21     if (n == 0)22         goto done;    /* connect completed immediately */23 24     FD_ZERO(&rset);25     FD_SET(sockfd, &rset);26     wset = rset;27     tval.tv_sec = nsec;28     tval.tv_usec = 0;29 30     if ( (n = Select(sockfd+1, &rset, &wset, NULL,31                      nsec ? &tval : NULL)) == 0) {32         close(sockfd);        /* timeout */33         errno = ETIMEDOUT;34         return(-1);35     }36 37     if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {38         len = sizeof(error);39         if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)40             return(-1);            /* Solaris pending error */41     } else42         err_quit("select error: sockfd not set");43 44 done:45     Fcntl(sockfd, F_SETFL, flags);    /* restore file status flags */46 47     if (error) {48         close(sockfd);        /* just in case */49         errno = error;50         return(-1);51     }52     return(0);53 }
View Code

select之后,如果描述符变为可读或可写,我们就调用getsockopt取得套接字的待处理错误。如果连接成功,该值将为0。

 

 

 

非阻塞connect:Web客户程序

在Web客户程序中。客户先建立一个与某个Web服务器的HTTP连接,再获取一个主页,该主页往往含有多个对于其他网页的引用。

客户可以使用非阻塞connect同时获取多个网页,以此取代每次只获取一个网页的串行获取手段。

 

0 0