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

套接字的默认状态时阻塞的

可能阻塞的套接字调用可分为以下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     } else

42         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同时获取多个网页,以此取代每次只获取一个网页的串行获取手段。

 

你可能感兴趣的:(学习笔记)