accpet和connect设置超时
三次握手
TCP连接建立的开始是三次握手,通过三次交互确认连接成功,在客户端调用connect时,客户端发送sync消息给服务端,服务端收到sync消息后,返回一个ack+sync,并等待ack,客户端收到ack+sync后,返回一个ack,connect返回,服务端收到ack后,accept返回,如下图所示:

connect超时设置
如果connect连接的服务端不存在,或是异常了,会出现什么情况,可能有以下几种情况:
服务端返回连接错误
等待系统默认的75秒超时
上述两种情况都是不可控的,因此可以通过设置超时时间的方式控制超时时间,有下述两种方法。
非阻塞connect+select
将conenct设置成非阻塞后,connect在发送sync后直接返回-1,然后使用select等待ack+sync,select是可以设置超时时间,因此达到设置超时时间的目的。注意需要将socket恢复成阻塞模式,如下所示:
dwSign = ;
if((err = ioctl(socket, FIONBIO, &dwSign)) < )
{
printf("ioctl socket failed, errno = %d!\n", err);
close(socket);
return err;
} SOCKADDR_IN tServerAddrInfo = {};
tServerAddrInfo.sin_family = AF_INET;
tServerAddrInfo.sin_addr.s_addr = ServerIP;
tServerAddrInfo.sin_port = ServerPort;
int bRet = 0x0;
fd_set set = {0x0};
if(- == connect(socket, (SOCKADDR*)&tServerAddrInfo, sizeof(SOCKADDR)))
{
tm.tv_sec = ;
tm.tv_usec = ;
FD_ZERO(&set);
FD_SET(socket, &set); // select返回值大于0,表示有数据可以操作;select返回值等于0,表示超时
if(select(socket + , NULL, &set, NULL, &tm) > )
{
// 获取socket的error值,0表示成功
getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
if(error == )
{
bRet = TRUE;
}
else
{
bRet = FALSE;
}
}
else
{
bRet = FALSE;
}
}
else
{
bRet = TRUE;
} dwSign = ;
if( > (err = ioctl(socket, FIONBIO, &dwSign)))
{
printf("ioctl socket failed, errno = %d!\n", err);
close(dwSocket);
return err;
}
设置socket的发送超时时间
调用connect函数实际上是发送sync报文,如果设置发送超时时间,那么也就可以实现connect的超时时间,如下所示:
struct timeval timeout = {, );
setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(struct timeval));
accpet超时设置
既然可以通过设置发送超时时间,控制connect的超时时间,那么同理,也可以通过设置接收超时时间来设置accept的超时时间,如下所示:
struct timeval timeout = {, };
setsockopt(proxy_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));
accpet和connect设置超时的更多相关文章
- connect设置超时的方法
在使用TCP的connect连接服务器时,在默认情况下系统使用的是阻塞式socket,如果服务器当前不可用,则connect会等待知道超时时间到达,而这个超时时间是系统内核规定的,并不能使用setSo ...
- 为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来说,是不能接受的.所以,我们能够在 ...
- 使用SIGALRM信号为阻塞操作设置超时
我们经常会遇到为阻塞操作设置超时的问题,比如说阻塞套接字read读取设置10秒超时,其中一个办法就是调用alarm函数,它在指定超时时期产生SIGALRM信号,使得阻塞操作中断. 但其弊端在于: 1. ...
- HttpClient库设置超时
HttpClient库API跟Lucene一样,每个版本的API都变化很大,这有点让人头疼.就好比创建一个HttpClient对象吧,每一个版本的都不一样. 3.X是正常的Java语法 HttpCli ...
- httpClient创建对象、设置超时
从老版本和新版本进行比较说明: 1.创建HttpClient对象 3.X: HttpClient httpClient = new DefaultHttpClient(); 4.3: Closeabl ...
- 测试setsockopt设置超时是否生效代码
// 测试setsockopt设置超时是否生效代码 #include <arpa/inet.h> #include <netinet/in.h> #include <st ...
随机推荐
- Java并发编程-Java内存模型
JVM内存结构与Java内存模型经常会混淆在一起,本文将对Java内存模型进行详细说明,并解释Java内存模型在线程通信方面起到的作用. 我们常说的JVM内存模式指的是JVM的内存分区:而Java内存 ...
- Java 中的数据结构类 Stack
JDK 中的 Stack 类便是经典的数据结构栈的实现,它继承于线程安全的 Vector 类,而且它自身的线程不安全的方法上也加上了 synchronized 关键字,所以它的内部操作也是线程安全的哦 ...
- SpringBoot — HelloWorld开发部署
springboot官方推荐使用jdk1.8 一.配置pom.xml 二.Application.java 三.HelloController.java 四.项目运行: Application.jav ...
- 【SpringMVC】
前言
- egret Exml自定义组件
有个需求,在A组件里面包裹 B组件: 碰到了一些奇怪的问题,这些问题是由于编辑器bug引起的.创建了皮肤后并没有在default.thm.json直接添加进去,造成拖动组件莫名其妙的bug,这里忘记保 ...
- js事件入门(6)
7.事件冒泡机制 7.1.什么是事件冒泡 当一个元素接收到一个事件以后,会将事件传播给它的父级元素,它的负级元素会一层一层往上传播,直到最顶层window,这种事件传播机制叫作事件冒泡. <!D ...
- RS232/485通信方式 保存和加载时数据的处理
RS232/485通信方式 数据以RS232/485方式通信时,以0xA5作为开始码,以0xAE作为结束码.在开始码和结束码之间的0xA5, 0xAA, 0xAE数据需要进行转码. PC端发送数据时将 ...
- 如何去除List集合中重复的元素
1.通过循环进行删除 public static void removeDuplicate(List list) { for ( int i = 0 ; i < list.size() - 1 ...
- java重试
项目中有很多需要重试的场景,而每次都得写如下的逻辑 for (int i=0;i++;i<retry){ try{ do(//逻辑代码); if(success){ break; } }catc ...
- sublime 搜索时忽略文件夹
如上图:添加 "folder_exclude_patterns": ["要忽略的文件夹"]