在使用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设置超时的方法的更多相关文章

  1. accpet和connect设置超时

    三次握手 TCP连接建立的开始是三次握手,通过三次交互确认连接成功,在客户端调用connect时,客户端发送sync消息给服务端,服务端收到sync消息后,返回一个ack+sync,并等待ack,客户 ...

  2. PHP file_get_contents设置超时处理方法

    从PHP5开始,file_get_content已经支持context了(手册上写着:5.0.0 Added the context support. ),也就是说,从5.0开始,file_get_c ...

  3. 为tcp的connect设置超时时间

    struct timeval tv = {timeout, 0}; 27   setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(s ...

  4. 使用SIGALARM为connect设置超时

    static void connect_alarm(int); int connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int ...

  5. 服务器编程入门(13) Linux套接字设置超时的三种方法

    摘要:     本文介绍在套接字的I/O操作上设置超时的三种方法. 图片可能有点宽,看不到的童鞋可以点击图片查看完整图片.. 1 调用alarm 使用SIGALRM为connect设置超时 设置方法: ...

  6. Unix网络编程 高级IO套接字设置超时

    我们知道.对于一个套接字的读写(read/write)操作默认是堵塞的.假设当前套接字还不可读/写,那么这个操作会一直堵塞下去,这样对于一个须要高性能的server来说,是不能接受的.所以,我们能够在 ...

  7. connect调用超时的实现方式

    第二种更通用的.使connect调用超时的方法是使套接字成为无阻塞的,然后用select等待它完成.这种方法避免了使用alarm时遇到的很多问题,但我们必须承认,即使是在UNIX实现中,这种方法还是存 ...

  8. Resttemplate中设置超时时长方法

    为了满足调用需求,需要在使用Resttemplate发送请求时,修改超时时长,网上给出了相关修改方法,代码如下: HttpComponentsClientHttpRequestFactory rf = ...

  9. HttpClient库设置超时

    HttpClient库API跟Lucene一样,每个版本的API都变化很大,这有点让人头疼.就好比创建一个HttpClient对象吧,每一个版本的都不一样. 3.X是正常的Java语法 HttpCli ...

随机推荐

  1. C语言函数实现的另类方法

    在前面看过那个BT的Javascript程序后,我们来看一个C语言的,相信大家还记得输出从1到1000的数最后的那个示例,本站还有很多这样的示例,如:变态的hello word,如何教新手编程,还有恐 ...

  2. Android Support Library 23.2介绍(翻译自官方文档)

    Android Support Library 23.2 (译者注:本文标注了部分文字链接,但须要***,要查看全部链接.请查看sukey=014c68f407f2d3e181b6b5e665f26a ...

  3. 如何使Android应用支持多种屏幕分辨率

    原文:http://android.eoe.cn/topic/android_sdk 描述: 让您指定您的应用支持的屏幕的大小并且可以通过屏幕兼容模式来支持比您应用所支持更大的屏幕.所以这对于您需要在 ...

  4. win10下快捷命令

    win10下可在win+r的输入框中: 1.gpedit.msc   //本地组策略编辑器 2.regedit    //注册表 3.secpol.msc   //本地安全策略 4.mstsc    ...

  5. vivado中设置多线程编译

    VIVADO中一个run编译时支持的线程数如下表:(综合时一般是2线程) Place Route Windows默认 2 2 Linux默认 4 4 Windows开启maxThreads=8 4 4 ...

  6. VS2010如何重置开发环境

    在利用VS进行软件开发的过程中,我们时不时要因为各种原因,对VS的开发环境进行变动,对于很多初次接触VS这样一个十分好用方便的编程工具的人来说,更改编程环境成了一个难题,今天我们就来讲解一下,如何更改 ...

  7. .net4.5使用async和await异步编程实例

    关于异步编程的简单理解: 在.NET4.5中新增了异步编程的新特性async和await,使得异步编程更为简单.通过特性可以将这项复杂的工作交给编译器来完成了.之前传统的方式来实现异步编程较为复杂,这 ...

  8. FLINK SQL Calcite原理

    http://wuchong.me/blog/2017/03/30/flink-internals-table-and-sql-api/ https://cloud.tencent.com/devel ...

  9. iOS开发-Tom猫

    // //  ViewController.m //  20-tom猫 // //  Created by hongqiangli on 2017/8/1. //  Copyright © 李洪强. ...

  10. EntityFramework安装和EF升级方法

    例如:如何在vs2010上安装EntityFramework5.0? 首先,需要安装一个vs插件,名称为NuGet Package Manager,微软官方发布的,其作用就是为vs工程项目自动下载.安 ...