本章讨论我们笼统地归为“高级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. [LOJ#2324]「清华集训 2017」小Y和二叉树

    [LOJ#2324]「清华集训 2017」小Y和二叉树 试题描述 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙 ...

  2. POJ2723 Get Luffy Out 【2-sat】

    题目 Ratish is a young man who always dreams of being a hero. One day his friend Luffy was caught by P ...

  3. [暑假集训--数论]poj2773 Happy 2006

    Two positive integers are said to be relatively prime to each other if the Great Common Divisor (GCD ...

  4. Render 使用

    Page页面文件,重新Render 方法,目的是把页面的ViewState信息放在最后,利于页面展示速度和SEO优化. Render方法对于重新Html控件还是很好用的. private static ...

  5. [bzoj 3048] [Usaco2013 Jan]Cow Lineup

    [bzoj 3048] [Usaco2013 Jan]Cow Lineup Description 给你一个长度为n(1<=n<=100,000)的自然数数列,其中每一个数都小于等于10亿 ...

  6. 遍历简单XML节点

    原文发布时间为:2009-08-26 -- 来源于本人的百度文章 [由搬家工具导入] <?xml version="1.0" encoding="gb2312&qu ...

  7. duilib入门简明教程 -- 响应按钮事件(4) (转)

    原文转自 http://www.cnblogs.com/Alberl/p/3343610.html     上一个Hello World的教程里有一句代码是这样的:CControlUI *pWnd = ...

  8. webview reload 错误 Error Domain=WebKitErrorDomain Code=102 "Frame load interrupted"

    在某个特定的场合先需要对WKWebView进行一次reload,但是直接回走到失败的代理方法中并报如下的错误 Error Domain=WebKitErrorDomain Code=102 " ...

  9. Cryptography I 学习笔记 --- 基于Diffie-Hellman的公钥加密

    1. Diffie-Hellman协议: 假定g是集合G的生成元,G有n个元素. Alice随机选取1-n中的一个数a,并公布ga为公钥 Bob随机选取1-n中的一个数b,并公布gb为公钥 那么gab ...

  10. HDU——最大连续子序列(区间DP)

    上一个题的加强版! 最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...