草庐IT

关于connect函数超时太久的问题(不同系统的默认超时时长不一,但都很久)

字正腔圆 2023-04-03 原文

解决方案思想:    通过把socket设置为非阻塞模式,然后通过select函数自己设置定时,检测套接字描述符是否可用。

windows端实现上代码: 过于粗略,仅呈思想

#include <winsock2.h>
#include <Windows.h>
#include <conio.h>
//#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
//#include <netinet/in.h>
//#include <arpa/inet.h>
//#include <sys/ioctl.h>
#include <stdarg.h>
//#include <fcntl.h>
#include <time.h>
int main(int argc, char *argv[]) 
{
    printf("==main===\n");fflush(stdout);
    //Winsows下启用socket
    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(1, 1), &wsadata) == SOCKET_ERROR) {
        printf("WSAStartup() fail\n");fflush(stdout);
        exit(0);
    }
    printf("==WSAStartup ok ===\n");fflush(stdout);
      int sockClient = socket(AF_INET, SOCK_STREAM, 0);
      struct sockaddr_in addrSrv;
      addrSrv.sin_addr.s_addr = inet_addr(argv[1]);
      addrSrv.sin_family = AF_INET;
      addrSrv.sin_port = htons(atoi(argv[2]));
 //fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0)|O_NONBLOCK); 
    printf("==goto  ioctlsocket ok ===\n");fflush(stdout);
    unsigned long ul=1;
     int ret=ioctlsocket(sockClient,FIONBIO,(unsigned long *)&ul);    //设置成非阻塞模式
    if(ret==SOCKET_ERROR)   //设置失败
    {
        printf("socket ioctl error%d\n", WSAGetLastError());fflush(stdout);
        return -10;
    }
    printf("==set sucess to connect===\n");fflush(stdout);
  int iRet = connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));
 printf("connect iRet is %d, errmsg:%s\n", iRet, strerror(errno));
 fflush(stdout); // 返回-1不一定是异常
 if (iRet != 0) 
 {
/*     
   if(errno != EINPROGRESS)
 {
  printf("connect error:%s\n", strerror(errno)); fflush(stdout);
 }
 else
     */
 {
  printf("socket ===========\n");
  struct timeval tm = {5, 0}; 
  fd_set wset, rset; 
  FD_ZERO(&wset); 
  FD_ZERO(&rset); 
  FD_SET(sockClient, &wset); 
  FD_SET(sockClient, &rset); 
  int time1 = time(NULL);
  int n = select(sockClient + 1, &rset, &wset, NULL, &tm); 
  int time2 = time(NULL);
  printf("time gap is %d\n", time2 - time1);fflush(stdout);
  if(n < 0) 
  { 
   printf("select error, n is %d\n", n); fflush(stdout);
  } 
  else if(n == 0) 
  { 
   printf("connect time out\n"); fflush(stdout);
  } 
  else if (n == 1) 
  {
   if(FD_ISSET(sockClient, &wset)) 
   { 
    printf("connect ok!\n"); fflush(stdout);
    //fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0) & ~O_NONBLOCK); 
   } 
   else
   { 
    printf("unknow error:%s\n", strerror(errno)); fflush(stdout);
   } 
  }
  else
  {
  printf("oh, not care now, n is %d\n", n);fflush(stdout);
  }
 } 
 } 
  printf("I am here!\n");fflush(stdout);
  //ioctlsocket(sockClient, FIONBIO, &ul); //设置为阻塞模式 阻塞时间为timeout时间
  getchar();
  closesocket(sockClient);
   
    WSACleanup();
    return 0;

}

 

 

linux端实现:

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
#include <time.h>
int main(int argc, char *argv[]) 
{
  int sockClient = socket(AF_INET, SOCK_STREAM, 0);
  struct sockaddr_in addrSrv;
  addrSrv.sin_addr.s_addr = inet_addr(argv[1]);
  addrSrv.sin_family = AF_INET;
  addrSrv.sin_port = htons(atoi(argv[2]));
  fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0)|O_NONBLOCK); 
  int iRet = connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));
  printf("connect iRet is %d, errmsg:%s\n", iRet, strerror(errno)); // 返回-1不一定是异常

 if (iRet != 0) 
 { 
   if(errno != EINPROGRESS)
   {
        printf("connect error:%s\n", strerror(errno)); 
   }
   else
   {
          struct timeval tm = {5, 0}; 
      fd_set wset, rset; 
      FD_ZERO(&wset); 
      FD_ZERO(&rset); 
      FD_SET(sockClient, &wset); 
      FD_SET(sockClient, &rset); 
      int time1 = time(NULL);
      int n = select(sockClient + 1, &rset, &wset, NULL, &tm); 
      int time2 = time(NULL);
      printf("time gap is %d\n", time2 - time1);
      if(n < 0) 
      { 
           printf("select error, n is %d\n", n); 
      } 
      else if(n == 0) 
      { 
           printf("connect time out\n"); 
      } 
      else if (n == 1) 
        {
         if(FD_ISSET(sockClient, &wset)) 
            { 
            printf("connect ok!\n"); 
            fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0) & ~O_NONBLOCK); 
         } 
         else
         { 
            printf("unknow error:%s\n", strerror(errno)); 
          } 
      }
       else
         {
           printf("oh, not care now, n is %d\n", n);
      }
    } 
  } 
  printf("I am here!\n");
  getchar();
  close(sockClient);
  return 0;
}
 

 

http://cache.baiducontent.com/c?m=YG5_oMGpXgIPmbhjnGo8iuOkg6r5BG-IOYPiHxsHndO7uml0F8mDauTl7Kgmpr0Hw3IFclRUo4wjnRZZTypvCOJrTUVpllsN8-It0LlsonT5YhmtpZpnciKQ0rrQlEtLEk4J2I7qmec2SC0QyazL1q&p=cb769a47898c13ff57ec966d5b40&newp=9c6fd10586cc40ad01a2c7710f5e92695d0fc20e3bd3da01298ffe0cc4241a1a1a3aecbf2c251b02d9c277620aad4e5ceff132743d0034f1f689df08d2ecce7e76c7&s=45c48cce2e2d7fbd&user=baidu&fm=sc&query=windows+connect&qid=89bd31ba0043d24b&p1=2

有关关于connect函数超时太久的问题(不同系统的默认超时时长不一,但都很久)的更多相关文章

  1. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  2. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  3. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  4. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  5. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  6. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  7. ruby-on-rails - Rails 优雅地处理超时 session ? - 2

    使用rails4,ruby2。我在rails配置中为我的cookiesession设置了30分钟的超时时间。问题是,如果我转到表单,让session超时,然后提交表单,我会收到此ActionController::InvalidAuthenticityToken错误。如何在Rails中优雅地处理这个错误?比如说,重定向到登录屏幕? 最佳答案 在您的ApplicationController:rescue_fromActionController::InvalidAuthenticityTokendoredirect_tosome_p

  8. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

    我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

  9. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

  10. ruby-on-rails - 将字符串转换为 ruby​​-on-rails 中的函数 - 2

    我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。

随机推荐