• <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>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運(yùn)轉(zhuǎn),開(kāi)心的工作
            簡(jiǎn)單、開(kāi)放、平等的公司文化;尊重個(gè)性、自由與個(gè)人價(jià)值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            getaddrinfo()詳解

            Posted on 2010-07-02 08:21 S.l.e!ep.¢% 閱讀(3732) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): VC

            getaddrinfo()詳解 收藏

            IPv4中使用gethostbyname()函數(shù)完成主機(jī)名到地址解析,但是該API不允許調(diào)用者指定 所需地址類(lèi)型的任何信息,返回的結(jié)構(gòu)只包含了用于存儲(chǔ)IPv4地址的空間。為了解決該問(wèn)題,IPv6中引入了getaddrinfo()的新API,它是 協(xié)議無(wú)關(guān)的,既可用于IPv4也可用于IPv6。調(diào)用該函數(shù)會(huì)獲得一個(gè)addrinfo結(jié)構(gòu)的列表,調(diào)用的返回值是addrinfo的結(jié)構(gòu)(列表)指針。

            ??????? 本文結(jié)合在WinowsXP和Windows2003 Server上使用該函數(shù)的經(jīng)驗(yàn),對(duì)getaddrinfo函數(shù)和addrinfo數(shù)據(jù)結(jié)構(gòu)進(jìn)行介紹,并對(duì)其參數(shù)的設(shè)置加以討論,主要包括 nodename和servname的取值對(duì)返回值的影響,hints成員變量的設(shè)置對(duì)返回值的影響等。

            可能有不完全或不準(zhǔn)確的地方,歡迎大家討論并指出。

            1 getaddrinfo函 數(shù)原型

            函數(shù)

            參數(shù)說(shuō)明

            int getaddrinfo(

            const char* nodename

            const char* servname,

            const struct addrinfo* hints,//

            struct addrinfo** res

            );

            nodename:節(jié)點(diǎn)名可以是主機(jī)名,也可以是數(shù)字地址。(IPV4的10進(jìn)點(diǎn)分,或是IPV6的16進(jìn)制)

            servname:包含十進(jìn)制數(shù)的端口號(hào)或服務(wù)名如(ftp,http)

            hints:是一個(gè)空指針或指向一個(gè)addrinfo結(jié)構(gòu)的指針,由調(diào)用者填寫(xiě)關(guān)于它所想返回的信息類(lèi)型的線索。

            res:存放返回addrinfo結(jié)構(gòu)鏈表的指針

            Getaddrinfo提供獨(dú)立于協(xié)議的名稱解析。

            函數(shù)的前兩個(gè)參數(shù)分別是節(jié)點(diǎn)名和服務(wù)名。節(jié)點(diǎn)名可以是主機(jī)名,也可以是地址串(IPv4的點(diǎn)分十進(jìn)制數(shù)表示或IPv6的十六進(jìn)制數(shù)字串)。服務(wù)名可 以是十進(jìn)制的端口號(hào),也可以是已定義的服務(wù)名稱,如ftp、http等。注意:其中節(jié)點(diǎn)名和服務(wù)名都是可選項(xiàng),即節(jié)點(diǎn)名或服務(wù)名可以為NULL, 此時(shí)調(diào)用的結(jié)果將取缺省設(shè)置,后面將詳細(xì)討論。

            函數(shù)的第三個(gè)參數(shù)hints是addrinfo結(jié)構(gòu)的指針,由調(diào)用者填寫(xiě)關(guān)于它所想返回的信息類(lèi)型的線索。函數(shù)的返回值是一個(gè)指向addrinfo 結(jié)構(gòu)的鏈表指針res。

            2 addrinfo結(jié)構(gòu)

            結(jié)構(gòu)

            固定的參數(shù)

            typedef struct addrinfo {??

            int ai_flags;??

            int ai_family;??

            int ai_socktype;??

            int ai_protocol;??

            size_t ai_addrlen;??

            char* ai_canonname;??

            struct sockaddr* ai_addr;??

            struct addrinfo* ai_next;

            }

            ai_addrlen must be zero or a null pointer

            ai_canonname must be zero or a null pointer

            ai_addr must be zero or a null pointer

            ai_next must be zero or a null pointer

            可以改動(dòng)的參數(shù)

            ai_flags:AI_PASSIVE,AI_CANONNAME,AI_NUMERICHOST

            ai_family: AF_INET,AF_INET6

            ai_socktype:SOCK_STREAM,SOCK_DGRAM

            ai_protocol:IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 etc.

            3 參數(shù)說(shuō)明

            在getaddrinfo函數(shù)之前通常需要對(duì)以下6個(gè)參數(shù)進(jìn)行以下設(shè)置:nodename、servname、hints的ai_flags、 ai_family、ai_socktype、ai_protocol

            在6項(xiàng)參數(shù)中,對(duì)函數(shù)影響最大的是nodename,sername和hints.ai_flag

            而ai_family只是有地址為v4地址或v6地址的區(qū)別。而ai_protocol一般是為0不作改動(dòng)。

            其中ai_flags、ai_family、ai_socktype說(shuō)明如下:

            參數(shù)

            取值

            說(shuō)明

            ai_family

            AF_INET

            2

            IPv4

            AF_INET6

            23

            IPv6

            AF_UNSPEC

            0

            協(xié)議無(wú)關(guān)

            ai_protocol

            IPPROTO_IP

            0

            IP協(xié)議

            IPPROTO_IPV4

            4

            IPv4

            IPPROTO_IPV6

            41

            IPv6

            IPPROTO_UDP

            17

            UDP

            IPPROTO_TCP

            6

            TCP

            ai_socktype

            SOCK_STREAM

            1

            SOCK_DGRAM

            2

            數(shù)據(jù)報(bào)

            ai_flags

            AI_PASSIVE

            1

            被動(dòng)的,用于bind,通常用于server socket

            AI_CANONNAME

            2


            AI_NUMERICHOST

            4

            地址為數(shù)字串

            對(duì)于ai_flags值的說(shuō)明:

            AI_NUMERICHOST

            AI_CANONNAME

            AI_PASSIVE

            0/1

            0/1

            0/1

            如上表所示,ai_flagsde值范圍為0~7,取決于程序如何設(shè)置3個(gè)標(biāo)志位,比如設(shè)置ai_flags為 “AI_PASSIVE|AI_CANONNAME”,ai_flags值就為3。三個(gè)參數(shù)的含義分別為:

            (1)AI_PASSIVE當(dāng)此標(biāo)志置位時(shí),表示調(diào)用者將在bind()函數(shù)調(diào)用中使用返回的地址結(jié)構(gòu)。當(dāng)此標(biāo)志不置位時(shí),表示將在 connect()函數(shù)調(diào)用中使用。

            當(dāng)節(jié)點(diǎn)名位NULL,且此標(biāo)志置位,則返回的地址將是通配地址。

            如果節(jié)點(diǎn)名NULL,且此標(biāo)志不置位,則返回的地址將是回環(huán)地址。

            (2)AI_CANNONAME當(dāng)此標(biāo)志置位時(shí),在函數(shù)所返回的第一個(gè)addrinfo結(jié)構(gòu)中的ai_cannoname成員中,應(yīng)該包含一個(gè)以空 字符結(jié)尾的字符串,字符串的內(nèi)容是節(jié)點(diǎn)名的正規(guī)名。

            (3)AI_NUMERICHOST當(dāng)此標(biāo)志置位時(shí),此標(biāo)志表示調(diào)用中的節(jié)點(diǎn)名必須是一個(gè)數(shù)字地址字符串。

            4.實(shí)際使用的幾種常用設(shè)置

            一般情況下,client/server編程中,server端調(diào)用bind(如果面向連接的還需要listen),client則不用掉bind 函數(shù),解析地址后直接connect(面向連接)或直接發(fā)送數(shù)據(jù)(無(wú)連接)。因此,比較常見(jiàn)的情況有

            (1)??????? 通常服務(wù)器端在調(diào)用getaddrinfo之前,ai_flags設(shè)置AI_PASSIVE,用于bind;主機(jī)名nodename通常會(huì)設(shè)置為 NULL,返回通配地址[::]。

            (2)??????? 客戶端調(diào)用getaddrinfo時(shí),ai_flags一般不設(shè)置AI_PASSIVE,但是主機(jī)名nodename和服務(wù)名servname(更愿意稱 之為端口)則應(yīng)該不為空。

            (3)??????? 當(dāng)然,即使不設(shè)置AI_PASSIVE,取出的地址也并非不可以被bind,很多程序中ai_flags直接設(shè)置為0,即3個(gè)標(biāo)志位都不設(shè)置,這種情況下 只要hostname和servname設(shè)置的沒(méi)有問(wèn)題就可以正確bind。

            上述情況只是簡(jiǎn)單的client/server中的使用,但實(shí)際在使用getaddrinfo和參考國(guó)外開(kāi)源代碼的時(shí)候,曾遇到一些將 servname(即端口)設(shè)為NULL的情況

            (當(dāng)然,此時(shí)nodename必不為NULL,否則調(diào)用getaddrinfo會(huì)報(bào)錯(cuò))。以下分情況進(jìn)行了測(cè)試:

            (1)??????? 如果nodename是字符串型的IPv6地址,bind的時(shí)候會(huì)分配臨時(shí)端口;

            (2)??????? 如果nodename是本機(jī)名,servname為NULL,則根據(jù)操作系統(tǒng)的不同略有不同,本文僅在WinXP和Win2003上作了測(cè)試。

            a)????????? WinXP系統(tǒng)(SP2)返回loopback地址[::1]

            b)???????? Win2003則將本機(jī)的所有IPv6地址列表加以返回。因?yàn)橥ǔR慌_(tái)IPv6主機(jī)都有可能不止一個(gè)IPv6地址,比如fe80::1(本機(jī) loopback地址)、fe80::***的Link-Local地址、3ffe:***的全局地址等等。這種情況下調(diào)用getaddrinfo會(huì)將這 些地址全部返回,調(diào)用者應(yīng)該注意如何使用這些地址。另外要注意的是,對(duì)于fe80::的地址在綁定的時(shí)候必須標(biāo)明接口地址,即使用 fe80::20d:60ff:fe78:51c2%4或fe80::1%1這樣的地址格式,通過(guò)getaddrinfo直接取出fe80地址好像無(wú)法直 接bind。

            日本精品久久久中文字幕| 久久精品国产清自在天天线| 精品一二三区久久aaa片| 国产免费久久精品丫丫| 久久婷婷五月综合色奶水99啪| 亚洲美日韩Av中文字幕无码久久久妻妇 | 亚洲人成电影网站久久| 99久久免费国产精品| 久久99热精品| 久久久青草久久久青草| 久久久噜噜噜久久中文福利| 国内精品九九久久精品| 成人综合久久精品色婷婷| 亚洲国产成人精品久久久国产成人一区二区三区综 | 久久久久久国产精品免费无码| 久久久www免费人成精品| 亚洲精品国精品久久99热| 久久天天躁狠狠躁夜夜不卡| 久久精品国产欧美日韩| 久久精品亚洲男人的天堂 | 久久久精品无码专区不卡| 久久精品二区| 日韩一区二区三区视频久久| 一级做a爰片久久毛片毛片| 久久久这里只有精品加勒比| 国内精品久久久久久久久电影网| 麻豆亚洲AV永久无码精品久久| 久久精品国产亚洲精品2020 | 欧美一级久久久久久久大| 一级A毛片免费观看久久精品| 久久人人爽人人爽人人片AV麻烦| 亚洲国产精品无码久久久蜜芽 | 91久久精品电影| 精品99久久aaa一级毛片| 久久久久综合中文字幕 | 久久综合久久自在自线精品自| 久久精品人人槡人妻人人玩AV| 777久久精品一区二区三区无码| 欧美久久亚洲精品| 久久99国产综合精品| 国产精品美女久久久免费|