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 }

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

非阻塞connect:Web客户程序

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

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

时间: 2024-11-02 19:09:50

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

UNP学习笔记(第六章 I/O复用)

I/O模型 首先我们将查看UNIX下可用的5种I/O模型的基本区别: 1.阻塞式I/O 2.非阻塞式I/O 3.I/O复用(select和poll) 4.信号驱动式I/O(SIGIO) 5.异步I/O(POSIX的aio_系列函数) 阻塞式I/O模型 最流行的I/O模型是阻塞式I/O模型,下面以数据报套接字作为例子,有如下的情形 非阻塞式I/O模型 进程把一个套接字设置成非阻塞式通知内核:当锁请求的I/O操作非得把本进程投入睡眠才能完成时,不要把本进程投入睡眠,而是返回一个错误 前三次调用rec

《JAVA编程思想》学习笔记——第十六章 数组

数组和其它种类的容器之间的区别有三方面:效率,类型和保存基本类型的能力.在Java中,数组是一种效率最高的存储和随机访问对象引用序列的方式.数组就是一个简单的线性序列,这使得元素访问非常快速.但是为这种速度所付出的代价是数组对象的大小被固定,并且在其生命周期中不可改变. 数组强调的是性能而不是灵活性 对象数组和基本类型数组在使用上几乎是相同的; 唯一的区别就是对象数组保存的是引用,基本类型数组直接保存基本类型的值. Arrays实用功能 System.arraycopy():复制数组 equal

iOS学习笔记(十六)——数据库操作(使用FMDB)

iOS中原生的SQLite API在使用上相当不友好,在使用时,非常不便.于是,就出现了一系列将SQLite API进行封装的库,例如FMDB.PlausibleDatabase.sqlitepersistentobjects等,FMDB (https://github.com/ccgus/fmdb) 是一款简洁.易用的封装库,这一篇文章简单介绍下FMDB的使用. 在FMDB下载文件后,工程中必须导入如下文件,并使用 libsqlite3.dylib 依赖包. FMDB同时兼容ARC和非ARC工

《Javascript权威指南》学习笔记之十六:BOM之源---BOM基本应用

BOM的基本应用包括:管理浏览器历史.解析地址和获取浏览器信息,本文将介绍这些应用. 一.浏览历史管理 1.history对象的方法和属性 History 对象包含用户(在浏览器窗口中)访问过的 URL,是 window 对象的一部分,可通过 window.history 属性对其进行访问.没有应用于 History 对象的公开标准,不过所有浏览器都支持该对象. length属性:返回浏览器历史列表中的URl数量.是"前进"和"后退"两个按钮之下包含的地址数的总和.

APUE学习笔记:第六章 系统数据文件和信息

6.1 引言 UNIX系统的正常运行需要使用大量与系统有关的数据文件,针对这些数据文件的可移植接口是本章的主题.本章还介绍了系统标识函数.时间和日期函数 6.2 口令文件 UNIX系统的口令文件包含了下列各字段,这些字段包含在<pwd.h>中定义的passwd结构中 用户名 char *pw_name 加密口令 char *pw_passwd 数值用户ID uid_t pw_uid 数值组ID gid_t pw_gid 注释字段 char *pw_gecos 初始工作目录 char *pw_d

Android学习笔记(十六)——碎片之间进行交互(附源码)

碎片之间进行交互 点击下载源码 很多时候,一个活动中包含一个或者多个碎片,它们彼此协作,向用户展示一个一致的UI.在这种情况下,碎片之间能进行通信并交换数据十分重要. 1.使用上一篇中创建的同一个项目,在fragment.xml中添加TextView的标识id: android:id="@+id/lblFragment1" 2.在fragment2.xml中添加一个Button,用于与fragment1进行交互: <Button android:id="@+id/btn

【Unity 3D】学习笔记二十六:unity游戏脚本(六)

在3D游戏世界中,任何一个游戏对象在创建的时候都会附带Transform(变换)组件,并且该组件是无法删除的,也不应该删除.在unity中,Transform面板一共有3个属性: Position  (位置) Rotation(旋转) Scale(缩放) 这三个值都是用来调整游戏对象在游戏界面中的位置,状态等相关参数. Position  (位置) 任何一个游戏对象的三维坐标都保存在Vector3容器中,该容器记录对象在X轴,Y轴,Z轴的坐标.一旦Vector33容器中的坐标发生变化,那么Sce

angular学习笔记(二十六)-$http(4)-设置请求超时

本篇主要讲解$http(config)的config中的timeout项: $http({ timeout: number }) 数值,从发出请求开始计算,等待的毫秒数,超过这个数还没有响应,则返回错误 demo: html: <!DOCTYPE html> <html ng-app = 'HttpGet'> <head> <title>18.4 $http(2)</title> <meta charset="utf-8"

马哥学习笔记二十六——MySQL主从复制

配置MySQL复制基本步骤: 一.master 1.启用二进制日志 log-bin = master-bin log-bin-index = master-bin.index 2.选择一个惟一server-id server-id = {0-2^32} 3.创建具有复制权限的用户 REPLICATION SLAVE REPLICATION CLIENT 二.slave 1.启用中继日志 relay-log = relay-log relay-log-index = 2.选择一个惟一的server