socket使用非阻塞connect
在使用tcp的connect调用时,默认是使用阻塞方式,当服务器当前不可用时,connect会等待(内部在重试?)直到超时时间到达,而这个超时时间是系统内核规定的,不能使用setSocketOpt来设置。
在碰到服务器不可用,上层逻辑进行重试时,如果超时时间过长,会产生卡死的感觉,用户体验也不佳,所以需要控制connect的超时时间。
参考网络上的资料,这里使用select。实现方式是:将socket设置为非阻塞方式,使用select来轮询socket,在select里指定超时时间,根据socket来判断连接状态。最后恢复socket的阻塞方式。
代码如下(linux):
int connect_with_timeout(int socket, const struct sockaddr *address, socklen_t address_len, int time_out)
{
int flag, old_flag;
old_flag = flag = fcntl(socket, F_GETFL, );
flag |= O_NONBLOCK;
fcntl(socket, F_SETFL, flag); int ret = -;
ret = ::connect(socket, (struct sockaddr*)address, address_len);
if (ret != ) {
if (errno != EINPROGRESS) {
LOG("connect failed,err(%d)", errno);
} else {
struct timeval tm;
tm.tv_sec = time_out;
tm.tv_usec = ;
fd_set set,rset;
FD_ZERO(&set);
FD_ZERO(&rset);
FD_SET(socket, &set);
FD_SET(socket, &rset); int res;
res = ::select(socket+, &rset, &set, NULL, &tm);
if (res < ) {
LOG("select:network error in connect.errno:%d", errno);
} else if(res == ) {
LOG("select:connect timeout.errno:%d", errno);
} else if (res == ) {
if (FD_ISSET(socket, &set)) {
LOG("select success");
ret = ;
}
} else {
LOG("other error when select: %s", strerror(errno));
}
}
} fcntl(socket, F_SETFL, old_flag); return ret;
}
::connect在非阻塞模式下会立即返回,如果没有其他错误,返回值等于0。
当::connect不能立即建立连接时,会返回EINPROGRESS,表示正在连接的过程中,这时可以使用select去轮询套接口,而select超时时间由参数指定 。
select返回值小于0,表明connect出错;等于0,表明connect超时;等于1,并且套接口的状态是可写,则表明connect已经成功建立。
最后恢复socket的阻塞属性。
参考:
http://olive101.blog.163.com/blog/static/2051263201011221915696/
socket使用非阻塞connect的更多相关文章
- linux 客户端 Socket 非阻塞connect编程
开发测试环境:虚拟机CentOS,windows网络调试助手 非阻塞模式有3种用途 1.三次握手同时做其他的处理.connect要花一个往返时间完成,从几毫秒的局域网到几百 ...
- 面向连接的socket数据处理过程以及非阻塞connect问题
对于面向连接的socket类型(SOCK_STREAM,SOCK_SEQPACKET)在读写数据之前必须建立连接,首先服务器端socket必须在一个客户端知道的地址进行监听,也就是创建socket之后 ...
- UNIX网络编程-非阻塞connect和非阻塞accept
1.非阻塞connect 在看了很多资料之后,我自己的理解是:在socket发起一次连接的时候,这个过程需要一段时间来将三次握手的过程走完,如果在网络状况不好或者是其他的一些情况下,这个过程需要比较长 ...
- TCP非阻塞accept和非阻塞connect
http://blog.chinaunix.net/uid-20751538-id-238260.html 非阻塞accept 当一个已完成的连接准备好被accept的时候,select会把监 ...
- Socket,非阻塞,fcntl
一.fcntl 用以下方法将socket设置成为非阻塞方式 int flags = fcntl(socket,F_GETFL,0); fcntl(socket,F_SETFL,flags|O_NON ...
- [Python]再学 socket 之非阻塞 Server
再学 socket 之非阻塞 Server 本文是基于 python2.7 实现,运行于 Mac 系统下 本篇文章是上一篇初探 socket 的续集, 上一篇文章介绍了:如何建立起一个基本的 sock ...
- UNIX网络编程——非阻塞connect: Web客户程序
非阻塞的connect的实现例子出自Netscape的Web客户程序.客户先建立一个与某个Web服务器的HTTP连接,再获取一个主页.该主页往往含有多个对于其他网页的引用.客户可以使用非阻塞conne ...
- 网络编程之非阻塞connect编写
一.connect非阻塞编写 TCP连接的建立涉及到一个三次握手的过程,且socket中connect函数需要一直等到客户接收到对于自己的SYN的ACK为止才返回, 这意味着每 个connect函数总 ...
- UE4 Socket多线程非阻塞通信
转自:https://blog.csdn.net/lunweiwangxi3/article/details/50468593 ue4自带的Fsocket用起来依旧不是那么的顺手,感觉超出了我的理解范 ...
随机推荐
- Ubuntu 无法登录 coursera 看视频
修改 host 文件 sudo vim /etc/hosts 将下面的内容添加至末尾 52.84.246.72 d3c33hcgiwev3.cloudfront.net
- js的常用正则表达式
1.在input框中只能输入金额,其实就是只能输入最多有两位小数的数字 //第一种在input输入框限制 <input type="text" maxlength=" ...
- Windows 下有什么软件能够极大地提高工作效率
Windows 下有什么软件能够极大地提高工作效率?修改 可以推荐一些好的应用或者有趣的程序,能提升工作效率或者能让人眼前一亮的.修改 举报1 条评论 分享 • 邀请回答 按票数排序按时间排序 2 ...
- cocos2d-x2.2+win7+vs2010+python安装配置
个人网站http://www.ravedonut.com/ 1.安装vs2010 2.解压cocos2d-x,打开cocos2d-win32.vc2012.sln,编译,然后运行Hellocpp成功即 ...
- 同步数据库bat脚本
在开发中, 如果需要将测试数据库同步到本地进行本地的测试, 可以执行一下脚本进行同步 @ECHO off TITLE databaseBackup REM : 该脚本会将 191 的 database ...
- Acyclic Organic Compounds
题意: 给一以1为根的字符树,给出每个节点的字符与权值,记 $diff_{x}$ 为从 $x$ 出发向下走,能走到多少不同的字符串,求问最大的$diff_{x} + c_{x}$,并求有多少个 $di ...
- CF-805D
D. Minimum number of steps time limit per test 1 second memory limit per test 256 megabytes input st ...
- codevs-1205
1205 单词翻转 题目描述 Description 给出一个英语句子,希望你把句子里的单词顺序都翻转过来 输入描述 Input Description 输入包括一个英语句子. 输出描述 Output ...
- kuangbin带你飞 - 合集
[题目列表] 之前有一些做过了的,这次从数论开始?
- Weekly Contest 111-------->944. Delete Columns to Make Sorted
We are given an array A of N lowercase letter strings, all of the same length. Now, we may choose an ...