• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            那誰的技術博客

            感興趣領域:高性能服務器編程,存儲,算法,Linux內核
            隨筆 - 210, 文章 - 0, 評論 - 1183, 引用 - 0
            數據加載中……

            帶超時機制的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定制的定時器,如果解決這些定時器可能發生的沖突問題?如果有更好的辦法,歡迎提示.



            posted on 2009-11-07 19:28 那誰 閱讀(9565) 評論(5)  編輯 收藏 引用 所屬分類: Linux/Unix

            評論

            # re: 帶超時機制的DNS解析API[未登錄]  回復  更多評論   

            可以用libevent的那個dns庫...
            2009-11-09 01:20 | bobo

            # re: 帶超時機制的DNS解析API  回復  更多評論   

            關鍵問題是有些 dns 解析失敗,有時返回 127.0.0.1 .

            2009-11-18 15:55 | hzh

            # re: 帶超時機制的DNS解析API  回復  更多評論   

            查了一下 可以通過alarm的返回值來判斷是否已經通過alarm定制了定時器
            SYNOPSIS
            #include <unistd.h>
            unsigned alarm(unsigned seconds);

            RETURN VALUE
            If there is a previous alarm() request with time
            remaining, alarm() shall return a non-zero value that
            is the number of seconds until the previous request
            would have generated a SIGALRM signal. Otherwise,
            alarm() shall return 0.
            2010-04-14 15:47 | bryan

            # re: 帶超時機制的DNS解析API  回復  更多評論   

            多線程怎么辦
            2010-12-09 13:59 | sss

            # re: 帶超時機制的DNS解析API  回復  更多評論   

            超時后原來創建的socket套接字無法關閉,會造成句柄被用完的問題。
            2014-12-01 14:51 | shifu
            91精品国产高清久久久久久国产嫩草| 蜜臀久久99精品久久久久久小说 | 亚洲国产成人久久综合野外| 久久精品国产一区二区电影| 亚洲性久久久影院| 久久国产精品77777| 国产精品久久久99| 午夜人妻久久久久久久久| 91精品国产高清91久久久久久 | 亚洲狠狠综合久久| 午夜精品久久久久久| 国产精品一久久香蕉国产线看观看 | 伊人久久综在合线亚洲2019| 亚洲精品国产综合久久一线| av国内精品久久久久影院| 久久国产三级无码一区二区| 久久国产乱子伦免费精品| 亚洲国产成人久久精品99 | 亚洲国产成人久久精品影视 | 狠狠色丁香久久婷婷综| 久久免费看黄a级毛片| 精品久久综合1区2区3区激情| 少妇人妻88久久中文字幕| 午夜精品久久影院蜜桃| 九九久久精品无码专区| 久久99国产精一区二区三区| 亚洲午夜久久久久久久久久| 久久涩综合| 久久久WWW成人| 久久久久这里只有精品| 国产精品伊人久久伊人电影| 亚洲伊人久久大香线蕉苏妲己| 午夜久久久久久禁播电影| 久久人妻少妇嫩草AV蜜桃| 久久人人爽人人爽人人爽| 思思久久99热只有频精品66| 亚洲欧美成人久久综合中文网 | 欧美丰满熟妇BBB久久久| 77777亚洲午夜久久多喷| 99精品久久久久久久婷婷| 亚洲成色WWW久久网站|