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 ...
随机推荐
- Jmeter 设置HTTP RPS性能测试模型
其实也挺简单的,主要是刚接触jmeter,记录一下. 1. 首先需要安装jmeter...真是废话... 2. 需要安装JMeterPlugins-ExtrasLibs-1.3.0.zip: JMet ...
- redis学习(三)五种数据结构
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 1.string string类型是Redis最基 ...
- Python基础教程笔记 第二章
本章的名字虽然叫列表和元组,但是本章讲的最多的是列表,元祖指讲了很少的一部分.因为元组和列表很多方面都是一样的. 列表和元组的区别:列表可以被修改,元祖不可以被修改. python包含的6种内建序列: ...
- Maven构建多模块项目
使用Maven构建多模块项目 转自:http://www.cnblogs.com/xdp-gacl/p/4242221.html 在平时的Javaweb项目 开发中为了便于后期的维护,我们一般会进行分 ...
- linux下常用的日志分析命令【转】
形如下面这样的access.log日志内容: 211.123.23.133 – - [10/Dec/2010:09:31:17 +0800] “GET /query/trendxml/district ...
- Codeforces 2014-2015 ACM-ICPC, NEERC, Southern Subregional Contest L. Useful Roads
L. Useful Roads time limit per test:4 seconds memory limit per test:512 megabytes input:standard inp ...
- POJ2478 Farey Sequence
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15023 Accepted: 5962 Description The ...
- AJAX在VS2005中的简单应用 使用ajaxpro.2.dll[点击按钮执行事件不刷新]
原文发布时间为:2008-10-21 -- 来源于本人的百度文章 [由搬家工具导入] 1.下載ajaxpro.dll或AjaxPro.2.dll 放在Bin文件夹中2.配置web.config 3.u ...
- 配置微信api调扫码功能
var url = encodeURIComponent(location.href.split('#')[0]); $.get(iapi+'/htweb/wx/getJsSdkSign?url='+ ...
- 让你的qstardict读单词
作为编程行当的人员,英语是躲不掉的,很多资料英文更加有效,字典就显得尤为重要,我希望字典不但能查到中文意思,还能发生,那就跟我来吧: 一.安装字典程序: pacman -S qstartdic sox ...