connect设置超时的方法
在使用TCP的connect连接服务器时,在默认情况下系统使用的是阻塞式socket,如果服务器当前不可用,则connect会等待知道超时时间到达,而这个超时时间是系统内核规定的,并不能使用setSocketOpt来设置,这个函数只能设置send和recv的超时,为了能够随意控制connect的超时时间,可以使用select。大致的过程就是先将socket设置成非阻塞,使用select去轮询套接口,再根据套接口去判断连接状态。
int connectServer(int sock_fd,unsigned int port,char* ip)
{
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
inet_aton(ip, &servaddr.sin_addr ); fcntl(sock_fd,F_SETFL,fcntl(sock_fd,F_GETFL,0)|O_NONBLOCK);
int connected = connect(sock_fd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in));
int ret = -1;
if (connected != 0 )
{
if(errno != EINPROGRESS)
printf("connect error :%s\n",strerror(errno));
else
{
struct timeval tm = {2, 0};
fd_set wset,rset;
FD_ZERO(&wset);
FD_ZERO(&rset);
FD_SET(sock_fd,&wset);
FD_SET(sock_fd,&rset);
long t1 = time(NULL);
int res = select(sock_fd+1,&rset,&wset,NULL,&tm);
long t2 = time(NULL);
printf("interval time: %ld\n", t2 - t1);
if(res < 0)
{
printf("network error in connect\n");
}
else if(res == 0)
{
printf("connect time out\n");
}
else if (1 == res)
{
if(FD_ISSET(sock_fd,&wset))
{
printf("connect succeed.\n");
fcntl(sock_fd,F_SETFL,fcntl(sock_fd,F_GETFL,0) & ~O_NONBLOCK);
ret = 0;
}
else
{
printf("other error when select:%s\n",strerror(errno));
}
}
}
} return ret;
}
程序先把socket设置成非阻塞,connect在非阻塞模式下会立刻返回,如果没有其他错误,返回值等于0。当connect不能立刻建立连接时,会返回一个EINPROGRESS,表示连接正在建立的过程中,这时我们可以使用select去轮询套接口,而select的轮询超时时间可以根据自己的需要去设置,最主要的是轮询的集合一定要是读和写的集合,即select的第二和第三个参数要赋值,待select返回就可以去判断返回值来确定connect的进程状态了。如果返回值小于0,说明connect的进程出现了错误,如果是等于0则说明connect超时,如果等于1,并且套接口此时的状态是可写,则说明了connect已经成功建立(关于这点大概是因为服务器接收了连接后,不会立刻想socket写数据,这是客户端就只能轮询到可写的socket,我觉得如果服务器接受连接并立刻写数据,在客户端就可能是返回2,这时学要同时判断socket的可读和可写了);其他情况的话就算是其他错误吧,至此,我们只需要设置select的超时值就可以随心所欲地实现自己想要的connect连接超时了。
最后,别忘了把套接口设置会阻塞状态,毕竟阻塞状态加线程方便控制。
https://blog.csdn.net/codeheng/article/details/44625495
connect设置超时的方法的更多相关文章
- accpet和connect设置超时
三次握手 TCP连接建立的开始是三次握手,通过三次交互确认连接成功,在客户端调用connect时,客户端发送sync消息给服务端,服务端收到sync消息后,返回一个ack+sync,并等待ack,客户 ...
- PHP file_get_contents设置超时处理方法
从PHP5开始,file_get_content已经支持context了(手册上写着:5.0.0 Added the context support. ),也就是说,从5.0开始,file_get_c ...
- 为tcp的connect设置超时时间
struct timeval tv = {timeout, 0}; 27 setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(s ...
- 使用SIGALARM为connect设置超时
static void connect_alarm(int); int connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int ...
- 服务器编程入门(13) Linux套接字设置超时的三种方法
摘要: 本文介绍在套接字的I/O操作上设置超时的三种方法. 图片可能有点宽,看不到的童鞋可以点击图片查看完整图片.. 1 调用alarm 使用SIGALRM为connect设置超时 设置方法: ...
- Unix网络编程 高级IO套接字设置超时
我们知道.对于一个套接字的读写(read/write)操作默认是堵塞的.假设当前套接字还不可读/写,那么这个操作会一直堵塞下去,这样对于一个须要高性能的server来说,是不能接受的.所以,我们能够在 ...
- connect调用超时的实现方式
第二种更通用的.使connect调用超时的方法是使套接字成为无阻塞的,然后用select等待它完成.这种方法避免了使用alarm时遇到的很多问题,但我们必须承认,即使是在UNIX实现中,这种方法还是存 ...
- Resttemplate中设置超时时长方法
为了满足调用需求,需要在使用Resttemplate发送请求时,修改超时时长,网上给出了相关修改方法,代码如下: HttpComponentsClientHttpRequestFactory rf = ...
- HttpClient库设置超时
HttpClient库API跟Lucene一样,每个版本的API都变化很大,这有点让人头疼.就好比创建一个HttpClient对象吧,每一个版本的都不一样. 3.X是正常的Java语法 HttpCli ...
随机推荐
- 20本最好的Linux免费书籍
前些天Neo推荐了一个网站有<超过100本的linux免费书籍>,这里,我也向大家推荐20本最好的Linux免费书籍,当然,也是英文版的. 1. Ubuntu Pocket Guide a ...
- 使用JDBC改变Oracle的session參数 NLS_DATE_FORMAT
近期项目除了一个问题,场景大概是这种,项目在国外开发.在项目开发过程中使用了大量的Oracle函数TO_DATE,可是开发者没有写第二个參数. 所以项目在国外的server上能够正常执行.但是在国内的 ...
- SharePoint 2013 Designer工作流——Parallel Block的应用
参考目录 安装和配置SharePoint 2013 Workflow SharePoint 2013 实现多级审批工作流 在自定义Workflow时,往往会遇到这样场景,某个审批需要被多人查阅,每个查 ...
- PostgreSQL创建数据库用户
注:版本不同,命令的执行路径可能有些不同. 一. 创建数据库用户freeswitch sudo -u postgres /usr/pgsql-9.5/bin/createuser -s -e free ...
- 解决tomcat服务器下,只能通过localhost,而不能通过127.0.0.1或者本地ip地址访问的问题
今天在tomcat上部署了一个web应用以后,发现用localhost的方式来访问应用是正常的,但是换成127.0.0.1或者是本地的ip地址来访问,确出现访问不了的情况.之前想是不是防火墙的问题,于 ...
- zTree变异篇:如何让同级树节点平铺而非垂直显示
昨天有一个zTree的使用者在实际的项目中有着这样一个特殊的需求,要求同级树节点能够水平显示,根据设定的宽度自动换行,效果图如下所示: 通过在浏览器调试模式下观察其同级节点的css为: 这个dis ...
- 用python参加Kaggle的经验总结【转】
用python参加Kaggle的经验总结 转载自:http://www.jianshu.com/p/32def2294ae6,作者 JxKing 最近挤出时间,用python在kaggle上试了 ...
- centOS7 安装man中文手册
[root@localhost ~]# yum list | grep man.*zh -.el7 base [root@localhost ~]# yum -y install man-pages- ...
- activiti工作流之Eclipse的Eclipse BPMN 2.0 Designer无法安装或者(安装后无法重复打开*.bpmn)
1.首先.既然学习activiti工作流,连官网和相应文件都没有下载就说不过去了 这是官网下载:http://www.activiti.org/download.html 2.对于下载后的activi ...
- mongoose的update函数中的回调函数是必须要传的吗
mongoose中的update的回调函数是必须要传的,如果不传,则不会更新. 例如这样写是不会更新的 tagModel.update({name:tagName},{$inc:{total:1}}, ...