三次握手

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设置超时的更多相关文章

  1. connect设置超时的方法

    在使用TCP的connect连接服务器时,在默认情况下系统使用的是阻塞式socket,如果服务器当前不可用,则connect会等待知道超时时间到达,而这个超时时间是系统内核规定的,并不能使用setSo ...

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

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

  3. 使用SIGALARM为connect设置超时

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

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

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

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

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

  6. 使用SIGALRM信号为阻塞操作设置超时

    我们经常会遇到为阻塞操作设置超时的问题,比如说阻塞套接字read读取设置10秒超时,其中一个办法就是调用alarm函数,它在指定超时时期产生SIGALRM信号,使得阻塞操作中断. 但其弊端在于: 1. ...

  7. HttpClient库设置超时

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

  8. httpClient创建对象、设置超时

    从老版本和新版本进行比较说明: 1.创建HttpClient对象 3.X: HttpClient httpClient = new DefaultHttpClient(); 4.3: Closeabl ...

  9. 测试setsockopt设置超时是否生效代码

    // 测试setsockopt设置超时是否生效代码 #include <arpa/inet.h> #include <netinet/in.h> #include <st ...

随机推荐

  1. Java并发编程-Java内存模型

    JVM内存结构与Java内存模型经常会混淆在一起,本文将对Java内存模型进行详细说明,并解释Java内存模型在线程通信方面起到的作用. 我们常说的JVM内存模式指的是JVM的内存分区:而Java内存 ...

  2. Java 中的数据结构类 Stack

    JDK 中的 Stack 类便是经典的数据结构栈的实现,它继承于线程安全的 Vector 类,而且它自身的线程不安全的方法上也加上了 synchronized 关键字,所以它的内部操作也是线程安全的哦 ...

  3. SpringBoot — HelloWorld开发部署

    springboot官方推荐使用jdk1.8 一.配置pom.xml 二.Application.java 三.HelloController.java 四.项目运行: Application.jav ...

  4. 【SpringMVC】

    前言

  5. egret Exml自定义组件

    有个需求,在A组件里面包裹 B组件: 碰到了一些奇怪的问题,这些问题是由于编辑器bug引起的.创建了皮肤后并没有在default.thm.json直接添加进去,造成拖动组件莫名其妙的bug,这里忘记保 ...

  6. js事件入门(6)

    7.事件冒泡机制 7.1.什么是事件冒泡 当一个元素接收到一个事件以后,会将事件传播给它的父级元素,它的负级元素会一层一层往上传播,直到最顶层window,这种事件传播机制叫作事件冒泡. <!D ...

  7. RS232/485通信方式 保存和加载时数据的处理

    RS232/485通信方式 数据以RS232/485方式通信时,以0xA5作为开始码,以0xAE作为结束码.在开始码和结束码之间的0xA5, 0xAA, 0xAE数据需要进行转码. PC端发送数据时将 ...

  8. 如何去除List集合中重复的元素

    1.通过循环进行删除 public static void removeDuplicate(List list) { for ( int i = 0 ; i < list.size() - 1 ...

  9. java重试

    项目中有很多需要重试的场景,而每次都得写如下的逻辑 for (int i=0;i++;i<retry){ try{ do(//逻辑代码); if(success){ break; } }catc ...

  10. sublime 搜索时忽略文件夹

    如上图:添加 "folder_exclude_patterns": ["要忽略的文件夹"]