带超时机制的DNS解析API

带超时机制的DNS解析API

根据域名解析出该域名所绑定的IP地址,这个是客户端常做的工作,只有在解析成功之后,才能正确的与服务器端建立连接.

一般常使用getaddrinfo,gethostbyname 之类的API来完成这个工作,但是,这些API都有一个问题,就是都不支持超时机制,假如客户端调用这些API阻塞,给程序会带来影响.

现在想要达到的目标就是:调用API去解析域名,如果在一个时间内不能解析成功,就报错退出.

我查了一下资料,有一些库可以支持这样的要求,但是都需要自己去做DNS解析的工作,也就是需要自己去封包/解包DNS协议报文.显然,这样的事情工作量太大了,不在我考虑的范围之中.

其实系统中有不少这样的API,没有阻塞机制,又不能设置超时参数,有没有一个好的策略,可以既使用这些API,又能给它们加上超时机制.

我看了下APUE中关于sigsetjmp + alarm + siglongjmp的方式来处理这样的问题,自己写了一个简单的demo,看来是可以满足的:
#include  < setjmp.h >
#include 
< stdio.h >
#include 
< sys / types.h >
#include 
< sys / socket.h >
#include 
< netdb.h >
#include 
< signal.h >
#include 
< string .h >

int  resolv_name( const   char *  url,  int  second);

int  main()
{
    resolv_name(
" www.test2test.com " 1 );
    
return   0 ;
}

static  sigjmp_buf                   jmpbuf;
static   volatile  sig_atomic_t        canjump;

static   void
sig_alrm(
int  signo)
{
    
if  ( ! canjump)
        
return ;

    siglongjmp(jmpbuf, 
1 );   /*  jump back to main, don't return  */
    canjump 
=   0 ;
}

int  resolv_name( const   char *  url,  int  second)
{
    
struct  addrinfo  * result  =  NULL;
    
int  ret;
    
struct  addrinfo addr;

    memset(
& addr,  0  ,  sizeof (addr));
    addr.ai_socktype 
=  SOCK_STREAM;

    
if  (signal(SIGALRM, sig_alrm)  ==  SIG_ERR)
        printf(
" signal(SIGALRM) error\n " );
    canjump 
=   1 ;
    
if  (sigsetjmp(jmpbuf,  1 )) 
    {
        printf(
" ending main\n " );
        
return   - 1 ;
    }

    alarm(second);

    ret 
=  getaddrinfo(url, NULL,  & addr,  & result);
    canjump 
=   0 ;

    
if  ( ! ret)
    {
        
struct  addrinfo  * pCurr  =  result;
        printf(
" the \'%s\' ip is:\n " , url);
        
for  (; pCurr; pCurr  =  pCurr -> ai_next)
        {
            printf(
" %s\n " , inet_ntoa((( struct  sockaddr_in * )(pCurr -> ai_addr)) -> sin_addr));
        }
    }

    
return   0 ;
}


不过这个策略还是有问题的,这个API通过alarm函数设定了一个定时器,超时的时候发送一个SIGALARM信号,如果系统中已经存在了通过alarm定制的定时器,如果解决这些定时器可能发生的冲突问题?如果有更好的办法,欢迎提示.



你可能感兴趣的:(带超时机制的DNS解析API)