本章讨论我们笼统地归为“高级I/O”的各个函数和技术

套接字超时

有3种方法在涉及套接字的I/O操作上设置超时

1.调用alarm,它在指定超时时期满时产生SIGALRM信号

2.在select中阻塞等待I/O(select有内置的时间限制),以此代替直接阻塞在read或write调用上

3.使用较新的SO_RCVTIMEO和SO_SNDTIMEO套接字选项。

使用SIGALRM为connect设置超时

下面给出我们的connect_timeo函数,它以调用者指定的超时上限调用connect

 /* include connect_timeo */
#include "unp.h" static void connect_alarm(int); int
connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec)
{
Sigfunc *sigfunc;
int n; sigfunc = Signal(SIGALRM, connect_alarm);
if (alarm(nsec) != )
err_msg("connect_timeo: alarm was already set"); if ( (n = connect(sockfd, saptr, salen)) < ) {
close(sockfd);
if (errno == EINTR)
errno = ETIMEDOUT;
}
alarm(); /* turn off the alarm */
Signal(SIGALRM, sigfunc); /* restore previous signal handler */ return(n);
} static void
connect_alarm(int signo)
{
return; /* just interrupt the connect() */
}
/* end connect_timeo */

如果connect被中断就会返回EINTR错误。

使用SIGALRM为recvfrom设置超时

 #include    "unp.h"

 static void    sig_alrm(int);

 void
dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE + ]; Signal(SIGALRM, sig_alrm); while (Fgets(sendline, MAXLINE, fp) != NULL) { Sendto(sockfd, sendline, strlen(sendline), , pservaddr, servlen); alarm();
if ( (n = recvfrom(sockfd, recvline, MAXLINE, , NULL, NULL)) < ) {
if (errno == EINTR)
fprintf(stderr, "socket timeout\n");
else
err_sys("recvfrom error");
} else {
alarm();
recvline[n] = ; /* null terminate */
Fputs(recvline, stdout);
}
}
} static void
sig_alrm(int signo)
{
return; /* just interrupt the recvfrom() */
}

使用select为recvfrom设置超时

 /* include readable_timeo */
#include "unp.h" int
readable_timeo(int fd, int sec)
{
fd_set rset;
struct timeval tv; FD_ZERO(&rset);
FD_SET(fd, &rset); tv.tv_sec = sec;
tv.tv_usec = ; return(select(fd+, &rset, NULL, NULL, &tv));
/* 4> 0 if descriptor is readable */
}
/* end readable_timeo */

该函数等待一个描述符变为可读或者发生超时(超时返回0)

我们可以使用该函数来改写上面的dg_cli函数

 #include    "unp.h"

 void
dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE + ]; while (Fgets(sendline, MAXLINE, fp) != NULL) { Sendto(sockfd, sendline, strlen(sendline), , pservaddr, servlen); if (Readable_timeo(sockfd, ) == ) {
fprintf(stderr, "socket timeout\n");
} else {
n = Recvfrom(sockfd, recvline, MAXLINE, , NULL, NULL);
recvline[n] = ; /* null terminate */
Fputs(recvline, stdout);
}
}
}

直到readable_timeo告知所关注的描述符已变为可读后我们才调用recvfrom(超时就打印错误)

使用SO_RCVTIMEO套接字选项为recvfrom设置超时

下面是使用SO_RCVTIMEO套接字选项的另一个版本的dg_cli函数

 #include    "unp.h"

 void
dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE + ];
struct timeval tv; tv.tv_sec = ;
tv.tv_usec = ;
Setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); while (Fgets(sendline, MAXLINE, fp) != NULL) { Sendto(sockfd, sendline, strlen(sendline), , pservaddr, servlen); n = recvfrom(sockfd, recvline, MAXLINE, , NULL, NULL);
if (n < ) {
if (errno == EWOULDBLOCK) {
fprintf(stderr, "socket timeout\n");
continue;
} else
err_sys("recvfrom error");
} recvline[n] = ; /* null terminate */
Fputs(recvline, stdout);
}
}

如果I/O操作超时,recvfrom将返回一个EWOULDBLOCK错误

read和write函数的变体

recv和send允许通过第四个参数从进程到内核传递标志;

readv和writev允许指定往其中输入数据或从其中输出数据的缓冲区向量;

recvmsg和sendmsg结合了其他I/O的所有特性,并具有接收和发送辅助数据的新能力

可以查看之前apue的学习笔记  http://www.cnblogs.com/runnyu/p/4648678.html

UNP学习笔记(第十四章 高级I/O函数)的更多相关文章

  1. 《机器学习实战》学习笔记第十四章 —— 利用SVD简化数据

    相关博客: 吴恩达机器学习笔记(八) —— 降维与主成分分析法(PCA) <机器学习实战>学习笔记第十三章 —— 利用PCA来简化数据 奇异值分解(SVD)原理与在降维中的应用 机器学习( ...

  2. JavaScript高级程序设计学习笔记第十四章--表单

    1.在 HTML 中,表单是由<form>元素来表示的,而在 JavaScript 中,表单对应的则是 HTMLFormElement 类型. HTMLFormElement 继承了 HT ...

  3. UNP学习笔记(第四章 基本TCP套接字编程)

    本章讲解编写一个完整的TCP客户/服务器程序所需要的基本套接字函数. socket函数 #include <sys/socket.h> int socket(int family,int ...

  4. 学习笔记 第十四章 使用CSS3动画

    第14章   使用CSS3动画 [学习重点] 设计2D动画 设计3D动画 设计过渡动画 设计帧动画 能够使用CSS3动画功能设计页面特效样式 14.1  设计2D动画 CSS2D Transform表 ...

  5. [HeadFirst-HTMLCSS学习笔记][第十四章交互活动]

    表单 <form action="http://wickedlysmart.com/hfhtmlcss/contest.php" method="POST" ...

  6. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化 学习目标 对Direct 3D编程在 ...

  7. VSTO学习笔记(十四)Excel数据透视表与PowerPivot

    原文:VSTO学习笔记(十四)Excel数据透视表与PowerPivot 近期公司内部在做一种通用查询报表,方便人力资源分析.统计数据.由于之前公司系统中有一个类似的查询使用Excel数据透视表完成的 ...

  8. Python学习笔记(十四)

    Python学习笔记(十四): Json and Pickle模块 shelve模块 1. Json and Pickle模块 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不 ...

  9. python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法

    python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...

随机推荐

  1. 第五篇:python基础_5

    本篇内容 协程函数 递归 二分法 import语句 from...import语句 模块搜索路径 包的导入 软件开发规范 logging模块的使用 一. 协程函数 1.定义 协程函数就是使用了yiel ...

  2. WS-*协议栈及相关概念

    1. 什么是WS-Security? WS-Security 是一个 SOAP 的扩展,它提供了对 SOAP 消息的认证和加密. 在介绍 WS-Security 之前,我们有必要了解一下 WS-Sec ...

  3. HDU 1392 Surround the Trees(凸包入门)

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. Understand:高效代码静态分析神器详解(一)【转】

    转自:http://www.codemx.cn/2016/04/30/Understand01/ 之前用Windows系统,一直用source insight查看代码非常方便,但是年前换到mac下面, ...

  5. msm8917 GPIO Voh(min)

    有些 pin 可以當成多種 function, 此例以 GPIO function P3 voltage 為例 Voh(min) = 1.67 - 0.45 = 1.22 V

  6. 关于main函数的参数

    #include <stdio.h> int main(int argc, char const *argv[]) { int i; for ( i = 0; i < argc; i ...

  7. 某考试T1 game

    题目背景 无 题目描述 Alice 和 Bob 在一个圆环上玩游戏.圆环上有 n 个位置,按照顺时针顺序 依次标号为 1 到 n.Alice 和 Bob 分别有一个数字集合,集合中都是在 [1, n− ...

  8. 2016集训测试赛(十九)Problem A: 24点大师

    Solution 这到题目有意思. 首先题目描述给我们提供了一种非常管用的模型. 按照题目的方法, 我们可以轻松用暴力解决20+的问题; 关键在于如何构造更大的情况: 我们发现 \[ [(n + n) ...

  9. SecureCRT鼠标快速复制粘贴

  10. Android 控件架构与自定义控件详解

    架构: PhoneWindow 将一个 DecorView 设置为整个应用窗口的根 View,这里面所有 View 的监听事件,都通过 WindowManagerService 来接收.DecorVi ...