大家好,欢迎来到IT知识分享网。
三次握手
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 = 1; if((err = ioctl(socket, FIONBIO, &dwSign)) < 0) { printf("ioctl socket failed, errno = %d!\n", err); close(socket); return err; } SOCKADDR_IN tServerAddrInfo = {0}; tServerAddrInfo.sin_family = AF_INET; tServerAddrInfo.sin_addr.s_addr = ServerIP; tServerAddrInfo.sin_port = ServerPort; int bRet = 0x0; fd_set set = {0x0}; if(-1 == connect(socket, (SOCKADDR*)&tServerAddrInfo, sizeof(SOCKADDR))) { tm.tv_sec = 10; tm.tv_usec = 0; FD_ZERO(&set); FD_SET(socket, &set); // select返回值大于0,表示有数据可以操作;select返回值等于0,表示超时 if(select(socket + 1, NULL, &set, NULL, &tm) > 0) { // 获取socket的error值,0表示成功 getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len); if(error == 0) { bRet = TRUE; } else { bRet = FALSE; } } else { bRet = FALSE; } } else { bRet = TRUE; } dwSign = 0; if(0 > (err = ioctl(socket, FIONBIO, &dwSign))) { printf("ioctl socket failed, errno = %d!\n", err); close(dwSocket); return err; }
设置socket的发送超时时间
调用connect函数实际上是发送sync报文,如果设置发送超时时间,那么也就可以实现connect的超时时间,如下所示:
struct timeval timeout = {10, 0); setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(struct timeval));
accpet超时设置
既然可以通过设置发送超时时间,控制connect的超时时间,那么同理,也可以通过设置接收超时时间来设置accept的超时时间,如下所示:
struct timeval timeout = {10, 0}; setsockopt(proxy_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/31714.html