我自横刀向天笑,去留肝胆两昆仑。这篇文章主要讲述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)
- 这两个选项的介绍可以参见文章:
- 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都是相同的
文章图片
二、演示案例(设置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(内核剖析):17---内核数据结构之二叉树(struct rb_rootstruct rb_node)
- Linux(内核剖析):21---中断之中断上下文中断处理机制的实现/proc/interrupts
- ES6深度解析-Classes
- Linux(程序设计):58---epoll复用技术实现统一处理信号事件源
- Linux(内核剖析):31---内核同步之(信号量(semaphore)读写信号量(rw_semaphore))
- MySQL数据库进阶篇
- 基于Sharding Sphere实现数据“一键脱敏”
- MySQL 数据库 增删查改克隆外键 等操作
- 经过我慎重考虑,决定把我自学Java基础的教程分享出来,一定收藏!