socket connect阻塞和非阻塞处理
建立socket后默认connect()函数为阻塞连接状态,在大多数实现中,connect的超时时间在75s至几分钟之间,想要缩短超时时间,可解决问题的两种方法:方法一、将socket句柄设置为非阻塞状态,方法二、采用信号处理函数设置阻塞超时控制。
在一个TCP套接口被设置为非阻塞之后调用connect,connect会立即返回EINPROGRESS错误,表示连接操作正在进行中,但是仍未完成;同时TCP的三路握手操作继续进行;在这之后,我们可以调用select来检查这个链接是否建立成功;非阻塞connect有三种用途:
1.我们可以在三路握手的同时做一些其它的处理.connect操作要花一个往返时间完成,而且可以是在任何地方,从几个毫秒的局域网到几百毫秒或几秒的广域网.在这段时间内我们可能有一些其他的处理想要执行;
2.可以用这种技术同时建立多个连接.在Web浏览器中很普遍;
3.由于我们使用select来等待连接的完成,因此我们可以给select设置一个时间限制,从而缩短connect的超时时间.在大多数实现中,connect的超时时间在75秒到几分钟之间.有时候应用程序想要一个更短的超时时间,使用非阻塞connect就是一种方法;
非阻塞connect听起来虽然简单,但是仍然有一些细节问题要处理:
1.即使套接口是非阻塞的,如果连接的服务器在同一台主机上,那么在调用connect建立连接时,连接通常会立即建立成功.我们必须处理这种情况;
2.源自Berkeley的实现(和Posix.1g)有两条与select和非阻塞IO相关的规则:
A:当连接建立成功时,套接口描述符变成可写;
B:当连接出错时,套接口描述符变成既可读又可写;
注意:当一个套接口出错时,它会被select调用标记为既可读又可写;
非阻塞connect有这么多好处,但是处理非阻塞connect时会遇到很多可移植性问题;
处理非阻塞connect的步骤:
第一步:创建socket,返回套接口描述符;
第二步:调用fcntl把套接口描述符设置成非阻塞;
第三步:调用connect开始建立连接;
第四步:判断连接是否成功建立;
A:如果connect返回0,表示连接简称成功(服务器可客户端在同一台机器上时就有可能发生这种情况);
B:调用select来等待连接建立成功完成;
如果select返回0,则表示建立连接超时;我们返回超时错误给用户,同时关闭连接,以防止三路握手操作继续进行下去;
如果select返回大于0的值,则需要检查套接口描述符是否可读或可写;如果套接口描述符可读或可写,则我们可以通过调用getsockopt来得到套接口上待处理的错误(SO_ERROR),如果连接建立成功,这个错误值将是0,如果建立连接时遇到错误,则这个值是连接错误所对应的errno值(比如:ECONNREFUSED,ETIMEDOUT等).
"读取套接口上的错误"是遇到的第一个可移植性问题;如果出现问题,getsockopt源自Berkeley的实现是返回0,等待处理的错误在变量errno中返回;但是Solaris会让getsockopt返回-1,errno置为待处理的错误;我们对这两种情况都要处理;
这样,在处理非阻塞connect时,在不同的套接口实现的平台中存在的移植性问题,首先,有可能在调用select之前,连接就已经建立成功,而且对方的数据已经到来.在这种情况下,连接成功时套接口将既可读又可写.这和连接失败时是一样的.这个时候我们还得通过getsockopt来读取错误值;这是第二个可移植性问题;
移植性问题总结:
1.对于出错的套接口描述符,getsockopt的返回值源自Berkeley的实现是返回0,待处理的错误值存储在errno中;而源自Solaris的实现是返回0,待处理的错误存储在errno中;(套接口描述符出错时调用getsockopt的返回值不可移植)
2.有可能在调用select之前,连接就已经建立成功,而且对方的数据已经到来,在这种情况下,套接口描述符是既可读又可写;这与套接口描述符出错时是一样的;(怎样判断连接是否建立成功的条件不可移植)
这样的话,在我们判断连接是否建立成功的条件不唯一时,我们可以有以下的方法来解决这个问题:
1.调用getpeername代替getsockopt.如果调用getpeername失败,getpeername返回ENOTCONN,表示连接建立失败,我们必须以SO_ERROR调用getsockopt得到套接口描述符上的待处理错误;
2.调用read,读取长度为0字节的数据.如果read调用失败,则表示连接建立失败,而且read返回的errno指明了连接失败的原因.如果连接建立成功,read应该返回0;
3.再调用一次connect.它应该失败,如果错误errno是EISCONN,就表示套接口已经建立,而且第一次连接是成功的;否则,连接就是失败的;
被中断的connect:
如果在一个阻塞式套接口上调用connect,在TCP的三路握手操作完成之前被中断了,比如说,被捕获的信号中断,将会发生什么呢?假定connect不会自动重启,它将返回EINTR.那么,这个时候,我们就不能再调用connect等待连接建立完成了,如果再次调用connect来等待连接建立完成的话,connect将会返回错误值EADDRINUSE.在这种情况下,应该做的是调用select,就像在非阻塞式connect中所做的一样.然后,select在连接建立成功(使套接口描述符可写)或连接建立失败(使套接口描述符既可读又可写)时返回;
方法二、定义信号处理函数:
- sigset(SIGALRM, u_alarm_handler);
- alarm(2);
- code = connect(socket_fd, (struct sockaddr*)&socket_st, sizeof(struct sockaddr_in));
- alarm(0);
- sigrelse(SIGALRM);
首先定义一个中断信号处理函数u_alarm_handler,用于超时后的报警处理,然后定义一个2秒的定时器,执行connect,当系统connect成功,则系统正常执行下去;如果connect不成功阻塞在这里,则超过定义的2秒后,系统会产生一个信号,触发执行u_alarm_handler函数, 当执行完u_alarm_handler后,程序将继续从connect的下面一行执行下去。
其中,处理函数可以如下定义,也可以加入更多的错误处理。
- void u_alarm_handler()
- {
- }
相关文章:

【ACM】CODE[VS] 2806(DFS)
感觉有点入了DFS的门槛,距离完全掌握还差得远呢 AC代码:运行时间为7ms #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn 26; int vis[maxn][maxn],col,line,flag,count; char map[…

scala学习手记34 - trait方法的延迟绑定
trait的方法的延迟绑定就是先混入的trait的方法会后调用。这一点从上一节的实例中也可以看出来。 下面再来看一个类似的例子: abstract class Writer {def write(message: String): String }trait UpperWriter extends Writer {abstract override def write(message…

(原創) Altera Technology Roadshow 2011 Taipei (SOC) (Quartus II) (Nios II) (Qsys)
Abstract這是我第一次參加Altera一年一度的Technology Roadshow。 Introduction 今年的Altera Technology Roadshow是在台北喜來登大飯店舉行。 位置在喜來登飯店的B2。 講師的講台。 當天的會場布置。 當天的演講內容,主要是台灣Altera兩家代理商Galaxy與Arrow的FA…

git-flow工作流说明
本文以一虚拟项目为例,描述了Git Flow在项目中的应用;还以此为主线,以表格形式给出了速查手册;最后,结合这两点介绍了一个基于Git Flow的项目实例。 希望这篇文章能够帮助Git初学者尽快上手。 1.1 什么是Git Fl…

2015湖南省省赛 阶乘除法 暴力
阶乘除法Time Limit:5000MS Memory Limit:65535KB 64bit IO Format: NBUT 1643Description 输入两个正整数 n, m,输出 n!/m!,其中阶乘定义为 n! 1*2*3*...*n (n>1)。 比如,若 n6, m3,则 n!/m!6!/3!720/6120。 是不是很简单?现在让我们把问题反过来:输入 kn!/m!,找到…

【ACM】POJ 1664
现在还不能理解为什么 至少有一个盘子用f(m,n-1)表示就可以了 AC: #include <iostream> #include <cstdio> using namespace std; int f(int m,int n) {if(m1 || n1 || m0) return 1;else if(m<n) return f(m,m);else{return f(m-n,n)f(m,n-1);} } int mai…

高效程序员的 7 个共同特征
导读:要想成为一个伟大的程序员,需要的可不仅仅是能够编写出可以正常运行的代码。Justin James给出了能够成为业内顶尖高手的程序员应该具有的几个典型特质。 要想成为高效的程序员,你需要具备一定的综合素质才能够让你用你所掌握的技能、经验…
Openstack组件实现原理 — Keystone认证功能
前言Keystone实现始终围绕着Keystone所实现的功能来展开,所以在理解其实现之前,建议大家尝试通过安装Keystone这一个过程来感受Keystone在Openstack架构中所充当的角色。下面给出了Keystone-M的安装过程。Keystone安装列表Openstack组件部署 — Overview…

unity test相关
http://www.throwtheswitch.org/unity

【小贴士】在线画流程图工具
https://c.runoob.com/more/shapefly-diagram/

Unity3D笔记 GUI 一
要实现的功能: 1、个性化Windows界面 2、减少个性化的背景图片尺寸 3、个性化样式ExitButton和TabButton 4、实现三个选项卡窗口 一、个性化Windows界面 1.1、创建一个空的GameObject、在Project中新建GUI Skin 用于绘制Windows图片 1.2 GUI Skin设置 1.3效…

gdb相关(栈和寄存器)
GDB的常用调试命令大家可以查阅gdb手册就可以快速的上手了,在这儿就不给大家分享了,需要的可以到GDB的官网去下载手册。这里重点分享下GDB调试中的一些寄存器和栈的相关知识用于解决下列gdb调试时的问题: 优化的代码在printf或其它glibc函数…

bzoj1688[Usaco2005 Open]Disease Manangement 疾病管理*
bzoj1688[Usaco2005 Open]Disease Manangement 疾病管理 题意: n头牛,d种疾病,每头牛都患一些疾病,现在要求选出最多的牛,使这些牛患病的种类数不超过k。n≤1000,d≤15 题解: 状压dp。f[i][S]表…

【数据结构】二叉树的应用。
1、分别采用递归和非递归的方式编写两个函数,求一棵给定二叉树中叶子节点的个数 2、返回一棵给定二叉树在中序遍历下的最后一个结点 3、假设二叉树采用链式方式存储,root为其根节点,p和q分别指向二叉树中任意两个结点,编写一个函…

我为我Windows Home Server 预热
这两天在下载Windows Home Server,所以找一些资料来看. 微软宣布Windows Home Server(WHS)正式推出,WHS是一个帮助家庭保护,连接并共享他们的数字媒体与文档的新解决方案。用户可以从各大在线商店进行预订,之后会在本月…

c 宏定义用法#define
转自:https://blog.csdn.net/boring_wednesday/article/details/78756696 宏定义 语法 #define name Stuff #define PI 3.14 //定义一个M,值为3.14 #define DO_FOREVER for(;;) //定义一个死循环 #define REG register //定义REG来作为register的别…

Linux学习笔记—— 权限及权限管理
权限及权限管理权限管理:r:w:x:三类用户:u:属主g:属组o:其他用户chown:改变文件属主(只有管理员可以使用此命令)# chown USERNAME file,...-R&…
【ACM】签到题
#include <stdio.h> int main () {int T,a,b,c,x,ji,ya,e;scanf("%d",&T);while(T--){scanf("%d%d%d%d",&a,&b,&c,&x);ya(a*x)/(c-b);e(a*b*x)/(a*c-a*b);jiex;printf("%d %d %d\n",ji,ya,e);}return 0; }
图解eclipse+myeclipse完全绿色版制作过程
现在在Java开发中,使用的开发工具大部分都是Eclipse,并且和Eclipse关系紧密的要数MyEclipse了,但是 MyEclipse是一个EXE可执行程序,对于没有安装Eclipse与MyEclilpse的电脑来说,首先得先解压Eclipse,然后再…

linux proc/xx/maps文件分析
转载:https://blog.csdn.net/lijzheng/article/details/23618365 Proc/pid/maps显示进程映射了的内存区域和访问权限。对应内核中的操作集为proc_pid_maps_op,具体的导出函数为show_map。内核中进程的一段地址空间用一个vm_area_struct结构体表示&#…
【ACM】熊孩子的乐趣
题目链接:http://acm.nuc.edu.cn/OJ/contest/show/43/1000 【问题描述】 Alice跟Bob是学校里出了名的两个熊孩子,会在任何事情上争个高低,彼此都不服输。幼儿园的老师每次分糖果的时候看到这两个熊孩子也很头疼,两个人都想占便宜…

mysql insertOrUpdate 方法
为什么80%的码农都做不了架构师?>>> 自己对这个方法又有点小心得 分享下 https://my.oschina.net/hccake/blog/777225 mysql "ON DUPLICATE KEY UPDATE" 语法 如果在INSERT语句末尾指定了ON DUPLICATE KEY UPDATE,并且插入行后会导…

软件破解工具整理收集
1.调试工具softice 2.调试工具Trw2000 3.反汇编工具Wdasm8.93 4.Hiew 5.Visual Basic程序调试工具Smartcheck 6.十六进制编辑器(如:Ultraedit、WinHex、Hex Workshop 等) 7.注册表监视工具RegShot、regmon或RegSnap 8.侦测文件类型工具…

Linux 下 UltraEdit 版本: 16.1.0.18 破解 30 天试用限制
rm -rfd ~/.idm/uex rm -rf ~/.idm/*.spl rm -rf /tmp/*.spl

【ACM】杭电OJ 2149
Public Sale 【问题描述】 虽然不想,但是现实总归是现实,Lele始终没有逃过退学的命运,因为他没有拿到奖学金。现在等待他的,就是像FarmJohn一样的农田生涯。 要种田得有田才行,Lele听说街上正在举行一场别开生面的拍…

PV UV IP
UV (网站独立访客) 编辑UV是unique visitor的简写,是指通过互联网访问、浏览这个网页的自然人。独立IP:是指独立用户/独立访客。指访问某个站点或点击某条新闻的不同IP地址的人数,在同一天的00:00-24:00内,…
VBA中级班课时3小结
本课内容:工作簿和工作表对象 主讲:rover18 学习时间:2010年11月 本节课将学习工作簿对象Workbooks、Workbook与工作表对象Worksheets、Worksheet。在我们了解了VBA的四大要素——对象、属性、方法和事件后,会发现VBA的程序是对对…

解决firefox ubuntu无法打开页面的问题
firefox备份用户配置信息 https://support.mozilla.org/zh-CN/kb/%E5%A4%87%E4%BB%BD%E4%BD%A0%E7%9A%84%E4%BF%A1%E6%81%AF 把xxxxxxxx.default 覆盖掉xxxxxxxx.default-release里面的内容

js构造函数式编程
1.函数式编程 //创建和初始化地图函数:function initMap(){createMap();//创建地图setMapEvent();//设置地图事件addMapControl();//向地图添加控件}//创建地图函数:function createMap(){var map new BMap.Map("dituContent");//在百度地图容…
【ACM】绝地求生
题目链接:http://acm.nuc.edu.cn/OJ/contest/show/43/1009 【问题描述】 zbt最近喜欢上了《绝地求生》(pubg)游戏,pubg这个游戏有一种跑毒机制,每次会产生一个圆形的安全区,玩家需要从他的当前位置在一定时间内进入安…