当前位置:   article > 正文

设置socket connect超时时间的几种方法_socket connect timeout

socket connect timeout

BSD
   

  1. int connectTimeout = 30;
  2. setsockopt(sock, IPPROTO_TCP, TCP_CONNECTIONTIMEOUT,(char *)&connectTimeout, sizeof(connectTimeout));


Linux
socket选项TCP_SYNCNT可以控制TCP连接SYN重传次数,默认为0,为0时SYN重传次数由系统参数 net.ipv4.tcp_syn_retries 控制,该系统参数默认值为6。

SYN重传次数影响connect超时时间,当重传次数为6时,超时时间为1+2+4+8+16+32+64=127秒。

   

  1. int syncnt = 4;
  2. setsockopt(sock, IPPROTO_TCP, TCP_SYNCNT, &syncnt, sizeof(syncnt));



使用select(Windows,Linux,BSD都可以用)
创建socket,将socket设置为非阻塞模式。
调用connect连接,如果能立即连接则返回0,不能立即连接返回-1,这个时候判断错误码是否表示暂时不能完成,是的话继续下一步。
接着调用select()在指定的时间内检测socket是否可写,如果可写表明connect()连接成功,0表示超时,-1表示出现了错误。
windows下代码:

  1. void attemptConnect(const char* ip,unsigned short port,int timeout)
  2. {
  3.     //初始化
  4.     WSADATA wsaData;
  5.     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) {
  6.         printf("WSAStartup function failed\n");
  7.         return;
  8.     }
  9.     SOCKET connectSocket= INVALID_SOCKET;
  10.     do {
  11.         //创建socket
  12.         connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  13.         if (connectSocket == INVALID_SOCKET) {
  14.             printf("socket function failed with error: %ld\n", WSAGetLastError());
  15.             break;
  16.         }
  17.         //socket设置为非阻塞 
  18.         unsigned long on = 1;
  19.         if (ioctlsocket(connectSocket, FIONBIO, &on) < 0) {
  20.             printf("ioctlsocket failed\n");
  21.             break;
  22.         }
  23.         //尝试连接
  24.         sockaddr_in clientService;
  25.         clientService.sin_family = AF_INET;
  26.         clientService.sin_addr.s_addr = inet_addr(ip);
  27.         clientService.sin_port = htons(port);
  28.         int ret = connect(connectSocket, (struct sockaddr*)&clientService, sizeof(clientService));
  29.         if (ret == 0) {
  30.             printf("connect success1\n");
  31.             return;
  32.         }
  33.         //因为是非阻塞的,这个时候错误码应该是WSAEWOULDBLOCK,Linux下是EINPROGRESS
  34.         if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK) {
  35.             printf("connect failed with error: %ld\n", WSAGetLastError());
  36.             return;
  37.         }
  38.         fd_set writeset;
  39.         FD_ZERO(&writeset);
  40.         FD_SET(connectSocket, &writeset);
  41.         timeval tv;
  42.         tv.tv_sec = timeout;
  43.         tv.tv_usec = 0;
  44.         ret = select(connectSocket + 1, NULL, &writeset, NULL, &tv);
  45.         if (ret == 0) {
  46.             printf("connect timeout\n");
  47.         } else if (ret < 0) {
  48.             printf("connect failed with error: %ld\n", WSAGetLastError());
  49.         } else {
  50.             printf("connect success2\n");
  51.         }
  52.     } while (false);
  53.     if (connectSocket != INVALID_SOCKET) {
  54.         closesocket(connectSocket);
  55.     }
  56.     WSACleanup();
  57. }
  58.  
  59. int main()
  60. {
  61.     attemptConnect("127.0.0.1",80,15);
  62.     system("pause");
  63.     return 0;
  64. }

————————————————
版权声明:本文为CSDN博主「土豆吞噬者」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiongya8888/article/details/96996236

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/225183
推荐阅读
相关标签
  

闽ICP备14008679号