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

  • 相关阅读:
    Java中的File类
    scala语法
    Spark核心原理
    资源调度器
    YARN工作机制
    MapReduce原理和工作过程
    序列化
    Hbase(2)表的设计和Rowkey等的设计
    Hbase(1)架构和工作原理
    Exception in thread "main" java.lang.NoSuchMethodError: io.netty.buffer.PooledByteBufAllocator.metric()Lio/netty/buffer/PooledByteBufAllocatorMetric;
  • 原文地址:https://www.cnblogs.com/runnyu/p/4667499.html
Copyright © 2011-2022 走看看