Linux(程序设计):60---定时机制之SO_RCVTIMEOSO_SNDTIMEO选项(附设置connect超时时间案例)

我自横刀向天笑,去留肝胆两昆仑。这篇文章主要讲述Linux(程序设计):60---定时机制之SO_RCVTIMEOSO_SNDTIMEO选项(附设置connect超时时间案例)相关的知识,希望能为你提供帮助。

  • Linux提供了三种定时方法,它们是:
    • socket选项SO_RCVTIMEO和SO_SNDTIMEO:本文要介绍的
    • SIGALRM信号,参见文章:javascript:void(0)
    • I/O复用系统调用的超时参数,参见文章:javascript:void(0)
  • Linux套接字超时介绍也可以参见这一篇文章的介绍:javascript:void(0)
一、SO_RCVRIMEO选项、SO_SNDTIMEO选项概述
  • 这两个选项的介绍可以参见文章:
    • javascript:void(0)
    • javascript:void(0)
  • SO_RCVTIMEO:设置socket接收数据超时时间
  • SO_SNDTIMEO:设置socket发送数据超时时间
  • 注意,访问它们的getsockopt和setsockopt函数的参数是指向timeval结构的指针,与select所用参数相同。这可让我们用秒数和微秒数来规定超时。我们通过设置其值为0s和0μs来禁止超时。默认 情况下这两个超时都是禁止的
  • 这两个选项可以设置于以下的系统调用:
    • 输入函数:read、readv、recv、recvfrom和recvmsg
    • 输出函数:write、writev、send、sendto和sendmsg
    • accept、connect
  • 超时后的行为:有些系统调用在下表未给出,但errno都是相同的
Linux(程序设计):60---定时机制之SO_RCVTIMEOSO_SNDTIMEO选项(附设置connect超时时间案例)

文章图片

二、演示案例(设置connect超时时间)
#include < stdio.h> #include < stdlib.h> #include < strings.h> #include < libgen.h> #include < errno.h> #include < unistd.h> #include < sys/time.h> #include < sys/socket.h> #include < sys/types.h> #include < arpa/inet.h> int timeout_connect(const char* ip,int port,int time); int main(int argc,char* argv[]) { if(argc!=3){ printf("usage:./%s [server ip] [server port]\\n",basename(argv[1])); exit(EXIT_FAILURE); }const char* ip; int client_fd,port,time; ip=argv[1]; port=atoi(argv[2]); time=10; client_fd=timeout_connect(ip,port,time); if(client_fd==-1) { close(client_fd); exit(EXIT_FAILURE); }printf("connect success!\\n"); close(client_fd); exit(EXIT_SUCCESS); }int timeout_connect(const char* ip,int port,int time) { int client_fd; //创建套接字 if((client_fd=socket(AF_INET,SOCK_STREAM,0))==-1){ perror("socket"); return -1; }//设置SO_SNDTIMEO超时选项 struct timeval timeout; timeout.tv_sec=time; timeout.tv_usec=0; socklen_t time_len=sizeof(timeout); if(setsockopt(client_fd,SOL_SOCKET,SO_SNDTIMEO,& timeout,time_len)==-1){ perror("setsockopt"); return -1; }//初始化服务器地址 struct sockaddr_in server_address; bzero(& server_address,sizeof(server_address)); server_address.sin_family=AF_INET; server_address.sin_port=htons(port); if(inet_pton(AF_INET,ip,& server_address.sin_addr)==-1){ perror("inet_pton"); return -1; }//连接服务端 printf("wait connect......\\n"); int connect_ret_value; if((connect_ret_value=https://www.songbingjia.com/android/connect(client_fd,(struct sockaddr*)& server_address,sizeof(server_address)))==-1){ if(errno==EINPROGRESS){ printf("connect timeout!\\n"); return -1; } perror("connect"); return -1; }return client_fd; }

代码测试
  • 我们使用这个程序去连接服务模拟工具,服务端工具没开启监听的时候,我们的程序连接超时
Linux(程序设计):60---定时机制之SO_RCVTIMEOSO_SNDTIMEO选项(附设置connect超时时间案例)

文章图片

  • 当我们将服务端工具开启监听之后,我们的程序连接成功
【Linux(程序设计):60---定时机制之SO_RCVTIMEOSO_SNDTIMEO选项(附设置connect超时时间案例)】
Linux(程序设计):60---定时机制之SO_RCVTIMEOSO_SNDTIMEO选项(附设置connect超时时间案例)

文章图片


    推荐阅读