本章讨论我们笼统地归为“高级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. BZOJ 1864:[Zjoi2006]三色二叉树(树DP)

    三色二叉树 问题描述 输入 仅有一行,不超过500000个字符,表示一个二叉树序列. 输出 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. 样例输入 1122002010 ...

  2. [LOJ#2323]「清华集训 2017」小Y和地铁

    [LOJ#2323]「清华集训 2017」小Y和地铁 试题描述 小Y是一个爱好旅行的OIer.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁. 她发现每条地铁线路可以看成平面上的 ...

  3. Codeforces Beta Round #95 (Div. 2) C 组合数学

    C. The World is a Theatre time limit per test 2 seconds memory limit per test 256 megabytes input st ...

  4. Object.keys(obj)

    对象.keys 很明显是获得对象的key的一个数组 数组的key arr = ['a', 'b', 'c']; console.log(Object.keys(arr)); // console: [ ...

  5. 两个Vue Demo

    1 实现 person list <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...

  6. iOS飘雪的动画小demo

    ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController{ UIImage ...

  7. ofbiz数据库表结构设计(3)- 订单ORDER

    对于订单来说,主要的表就是ORDER_HEADER和ORDER_ITEM.ORDER_HEADER就是所谓的订单头,一条记录代表一条订单. ORDER_PAYMENT_PREFERENCE是订单的支付 ...

  8. POJ3687 Labeling Balls

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13645   Accepted: 3955 Description Wind ...

  9. [论文]Clustering-Based Ensembles as an Alternative to Stacking

    Clustering-Based Ensembles as an Alternative to Stacking 作者:Anna Jurek, Yaxin Bi, Shengli Wu, and Ch ...

  10. Codeforces 920G List Of Integers 二分 + 容斥

    题目链接 题意 给定 \(x,p,k\),求大于 \(x\) 的第 \(k\) 个与 \(p\) 互质的数. 思路 参考 蒟蒻JHY. 二分答案 \(y\),再去 \(check\) 在 \([x,y ...