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

  • 相关阅读:
    IntelliJ IDEA 2017版 SpringBoot的核心配置详解
    路由追踪程序traceroute/tracert分析与科普
    traceroute追踪路由命令
    ping 命令
    hostname命令,修改主机名及host文件
    net-tools工具arp命令
    ifup 和 ifdown
    net-tools工具ifconfig 命令
    iproute2 对决 net-tools
    什么是带内管理 带外管理
  • 原文地址:https://www.cnblogs.com/runnyu/p/4667499.html
Copyright © 2020-2023  润新知