UNP学习笔记(第十四章 高级I/O函数)
本章讨论我们笼统地归为“高级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函数)的更多相关文章
- 《机器学习实战》学习笔记第十四章 —— 利用SVD简化数据
相关博客: 吴恩达机器学习笔记(八) —— 降维与主成分分析法(PCA) <机器学习实战>学习笔记第十三章 —— 利用PCA来简化数据 奇异值分解(SVD)原理与在降维中的应用 机器学习( ...
- JavaScript高级程序设计学习笔记第十四章--表单
1.在 HTML 中,表单是由<form>元素来表示的,而在 JavaScript 中,表单对应的则是 HTMLFormElement 类型. HTMLFormElement 继承了 HT ...
- UNP学习笔记(第四章 基本TCP套接字编程)
本章讲解编写一个完整的TCP客户/服务器程序所需要的基本套接字函数. socket函数 #include <sys/socket.h> int socket(int family,int ...
- 学习笔记 第十四章 使用CSS3动画
第14章 使用CSS3动画 [学习重点] 设计2D动画 设计3D动画 设计过渡动画 设计帧动画 能够使用CSS3动画功能设计页面特效样式 14.1 设计2D动画 CSS2D Transform表 ...
- [HeadFirst-HTMLCSS学习笔记][第十四章交互活动]
表单 <form action="http://wickedlysmart.com/hfhtmlcss/contest.php" method="POST" ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化 学习目标 对Direct 3D编程在 ...
- VSTO学习笔记(十四)Excel数据透视表与PowerPivot
原文:VSTO学习笔记(十四)Excel数据透视表与PowerPivot 近期公司内部在做一种通用查询报表,方便人力资源分析.统计数据.由于之前公司系统中有一个类似的查询使用Excel数据透视表完成的 ...
- Python学习笔记(十四)
Python学习笔记(十四): Json and Pickle模块 shelve模块 1. Json and Pickle模块 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不 ...
- python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法
python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...
随机推荐
- Ubuntu下建立Pycharm快捷方式
修改 Exec, Icon 路径,将文件保存 pycharm.desktop,拖到unity侧边栏 [Desktop Entry]Categories=Development;Comment[zh_C ...
- BZOJ 3876 支线剧情(有上下界的无源汇最小费用可行流)
3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 1783 Solved: 1079 [Submit][St ...
- [AHOI2014&&JSOI2014][bzoj3876] 支线剧情 [上下界费用流]
题面 传送门 思路 转化模型:给一张有向无环图,每次你可以选择一条路径走,花费的时间为路径上边权的总和,问要使所有边都被走至少一遍(可以重复),至少需要花费多久 走至少一遍,等价于覆盖这条边 也就是说 ...
- Windows系统——后缀为.zip.00X的zip分卷解压
Windows下后缀为*.zip.001文件的解压方法: 后缀为*.zip.001文件用winrar无法解压, 解决办法是在windows下打开命令行界面, 输入:copy /B xx.zip.001 ...
- 使用docker-maven-plugin插件构建docker镜像(已过时)
可以参考博客:https://blog.csdn.net/aixiaoyang168/article/details/77453974 docker-maven-plugin官网推荐在新项目中使用do ...
- 洛谷 [P3620] 数据备份
贪心神题 首先我们发现一个显然的贪心策略,连接相邻两个写字楼总是更优. 所以本题就变成了数轴上一堆点,要选 k 个彼此不相邻的区间,使得区间长度最小 对于 10000 的数据来说,我们可以用 DP 解 ...
- 【BZOJ4481&JSOI2015】非诚勿扰(数学期望)
听说JSOI有版权问题就不放图了 如果前面的文章里的图需要删掉请通知我 题意:有一些女的要挑一些男的,挑中的几率均为p.一个男的可以无限次被挑中.若女a选中男b,女c选中男d,a<c,b> ...
- [LeetCode] Merge Intervals 排序sort
Given a collection of intervals, merge all overlapping intervals. For example,Given [1,3],[2,6],[8,1 ...
- [原创] 树莓派个人实测 Q&A(最新修改使用windows连接远程桌面)
原文出处:http://www.eeboard.com/bbs/thread-5191-1-1.html 这篇帖子我打算用Q&A的方式来编写,这样大家更容易一目了然的看明整个帖子的内容,层次分 ...
- token in c and cpp (C preprocessor)
C tokens are of six types, They are, keyword identifier constant string-literal punctuator preproces ...