最近项目中,有个需求是检测某ip地址是否是通的,使用了socket的connect函数。但是,当ip地址写错的话,connect就会一直阻塞在那里,大概2、3分钟才能返回连接失败。这对于用户来说是不可接受的。下面的文章介绍了两种方法实现这种超时设置:

转自http://blog.csdn.net/ast_224/article/details/2957294

 connect超时:

目前各平台通用的设置socket connect超时的办法是通过select(),具体方法如下:

.建立socket;
.将该socket设置为非阻塞模式;
.调用connect();
.使用select()检查该socket描述符是否可写;
.根据select()返回的结果判断connect()结果;
.将socket设回阻塞模式。
    //设socket为非阻塞
unsigned long ul=;
int rm=ioctl(sockfd,FIONBIO,&ul);
if(rm==-)
{
close(sockfd);
return ;
} if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == )
{
printf("connected/n");//正常连接(小小:使用gdb调试时,从来走不到这一步"设置为非阻塞,connect调用后,无论连接是否建立立即返回-1")
}
if(errno!=EINPROGRESS)//若errno不是EINPROGRESS,则出错(EINPROGRESS:以非阻塞的方式来进行连接的时候,返回的结果如果是 -1,这并不代表这次连接发生了错误,如果它的返回结果是 EINPROGRESS,那么就代表连接还在进行中)
{
perror("connect");
printf("cannot connect:%s/n",server);
return ;
}
//使用select设置超时
struct timeval timeout;
fd_set r;
FD_ZERO(&r);
FD_SET(sockfd,&r);
timeout.tv_sec=;
timeout.tv_usec=;
int retval = select(sockfd+,NULL,&r,NULL,&timeout);
if(retval==-)
{
perror("select");
return ;
}
else if(retval == )
{
fprintf(stderr,"Timeout/n");
return ;
}
printf("%sconnected/n",server);
//将socket设置回正常的阻塞模式
ul1=;
rm=ioctl(sockfd,FIONBIO,(unsigned long*)&ul1);
if(rm==-)
{
close(sockfd);
return ;
}

以上代码工作的很好,并且也可以通过getsockopt()获得连接发生错误的确切信息,但这总方法难免觉得有些复杂,因为要涉及到阻塞状态的解除和回置。

这里有个简单的操作方法,同样可以设置连接超时:即通过SO_SNDTIMO套节字参数。

原因是:Linux内核源码中connect的超时参数和SO_SNDTIMO操作的参数一致。

因此,在linux平台下,可以通过connect之前设置SO_SNDTIMO来达到控制连接超时的目的。

    struct timeval timeo;
socklen_t len = sizeof(timeo);
timeo.tv_sec = overtime; if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len) == -)
{
strcpy(reason,strerror(errno));
perror("setsockopt");
return ;
} their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(serverStruct->port);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero), ); if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -)
{
if (errno == EINPROGRESS)
{
strcpy(reason,"timeout");
return ;
}
strcpy(reason,strerror(errno));
perror("connect");
return ;
}

小小:上述两种实现方式都可以达到目的。第二种比较简单,利用直接修改connect内部实现用到的参数。但是这种方式可能会产生其他问题吧?(我不确定),可能会影响到其他socket编程接口的超时设定。根据SO_SNDTIMO字面意思来看,是send time out的意思,感觉可能会影响某些发送数据的函数,比如send

connect socket的超时设置的更多相关文章

  1. C# Socket连接超时设置

    问题描述:         对于C# Socket没有超时设置的选项,默认情况下进行Socket连接,返回连接失败需要20-30s时间,严重影响用户体验 问题解决: Socket服务器端: Socke ...

  2. [转]c# winform tcp connect timeout 连接超时设置

    转自:https://www.cnblogs.com/jhlong/p/5622336.html 简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的 ...

  3. perl Socket接收超时设置

    一般来说, IO::Socket::INET里的Timeout设置是对于conncet的 如果你想设置recv接收超时, 可以这样设置: usr Socket: ...... , )); #注意这里p ...

  4. socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto

    socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...

  5. C++ Socket超时设置

    用winsocket时,send(),recv()过程中有时由于网络状况等原因,收发不能预期进行,可以设置收发时限:int nNetTimeout = 1000; //1秒//发送时限setsocko ...

  6. Socket编程实践(9) --套接字IO超时设置方法

    引:超时设置3种方案 1. alarm超时设置方法 //代码实现: 这种方式较少用 void sigHandlerForSigAlrm(int signo) { return ; } signal(S ...

  7. PHP socket 编程中的超时设置

    PHP socket 编程中的超时设置.网上找了半天也没找到.贴出来分享之:设置$socket 发送超时1秒,接收超时3秒: $socket = socket_create(AF_INET,SOCK_ ...

  8. python设置socket的超时时间(可能使用locust压测千级并发的时候要用到,先记录在此)

    在使用urllib或者urllib2时,有可能会等半天资源都下载不下来,可以通过设置socket的超时时间,来控制下载内容时的等待时间. 如下python代码 import socket timeou ...

  9. Socket连接超时(转)

    Socket.connect连接超时有二种情况: 1.由于网络的问题,TCP/IP三次握手时间>timeout的设置时间.这在国外访问weibo时,并且网络环境极差的情况下有可能发生.解决的办法 ...

随机推荐

  1. 闭包创建自己的 plugin 示例 加载 loading

    plugin  插件 什么是 plugin? 实现一个功能,与主应用程序分离,减少主应用程序的大小,高复用,可维护 制作过程中,一定要避免依赖其他的元素,减少 id 等的使用,避免与页面中其他内容冲突 ...

  2. mvc 返回一个对象 到视图接收

    public ActionResult InfoFrame() { List<Users> list = new List<Users>(); Users user = new ...

  3. day 15 - 1 内置函数

    内置函数 作用域相关 locals() globals() #这两组开始容易搞混 print(locals()) #返回本地作用域中的所有名字 print(globals()) #返回全局作用域中的所 ...

  4. Bmob后端云学习(未完)

    Bmob后端云学习 BaaS(后端即服务:Backend as a Service)公司为移动应用开发者提供整合云后端的边界服务. 这种服务的一个代表就是Bmob后端云,BAT和亚马逊 ,都有这类产品 ...

  5. XML与HTML的作用不同

    1. html是用来显示数据的:xml是用来描述数据.存放数据的,所以可以作为持久化的介质!Html将数据和显示结合在一起,在页面中把这数据显示出来:xml 则将数据和显示分开. XML被设计用来描述 ...

  6. 解决nginx和php使用ckfinder无法上传大文件的问题

    现象描述:cms内容发布系统上传不了大文件,当上传超过32M文件时就上传不了 提示:无效的文件. 文件尺寸太大. 分析文件上传过程:browser --> nginx --> php 需要 ...

  7. CSS选择器权重计算

    CSS各种选择器的权重: 1.ID选择器  +100 2.类.属性.伪类选择器   +10 3.元素.伪元素选择器   +1 4.其他选择器   +0 如果有两个CSS样式都作用于某元素,如: #id ...

  8. 基于Python+Django重定向的例子

    Django源码, 这里HttpResponseRedirect和HttpResponsePermanentRedirect没有太大差别,前者是返回302临时重定向,后者返回301永久重定向 clas ...

  9. SQL Server2012如何导出sql脚本并且还原数据库

    一  备份数据库 1  选择某一个数据库,右键依次选择:任务==>生成脚本: 2  选择要编写脚本的数据库对象,注意此处可以选择特定的数据库对象,我们可以选择我们需要备份的数据表. 3   在当 ...

  10. SpringBoot之hello world!

    哈哈哈,还是在元旦这一天对你下手了.麻溜的给自己充电,在这个寒冬,不断听到裁员的消息或者新闻,可对于我这个外包和外派的人来说,好像并没有受到什么影响.可能是人手不够可能是项目很忙.对于明年的三月金四月 ...