<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 網絡,第 2 部分:使用 getaddrinfo > 原文:<https://github.com/angrave/SystemProgramming/wiki/Networking%2C-Part-2%3A-Using-getaddrinfo> ## 如何使用`getaddrinfo`將主機名轉換為 IP 地址? 函數`getaddrinfo`可以將人類可讀域名(例如`www.illinois.edu`)轉換為 IPv4 和 IPv6 地址。實際上它將返回 addrinfo 結構的鏈表: ```c struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; socklen_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }; ``` 它非常易于使用。例如,假設您想在 [www.bbc.com](http://www.bbc.com) 中找到網絡服務器的數字 IPv4 地址。我們分兩個階段完成。首先使用 getaddrinfo 構建可能的連接的鏈表。其次使用`getnameinfo`將二進制地址轉換為可讀形式。 ```c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> struct addrinfo hints, *infoptr; // So no need to use memset global variables int main() { hints.ai_family = AF_INET; // AF_INET means IPv4 only addresses int result = getaddrinfo("www.bbc.com", NULL, &hints, &infoptr); if (result) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(result)); exit(1); } struct addrinfo *p; char host[256],service[256]; for(p = infoptr; p != NULL; p = p->ai_next) { getnameinfo(p->ai_addr, p->ai_addrlen, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST); puts(host); } freeaddrinfo(infoptr); return 0; } ``` 典型輸出: ``` 212.58.244.70 212.58.244.71 ``` ## [www.cs.illinois.edu](http://www.cs.illinois.edu) 如何轉換為 IP 地址? 魔法!不用說,使用稱為“DNS”(域名服務)的系統。如果計算機沒有在本地保存答案,則它會將 UDP 數據包發送到本地 DNS 服務器。該服務器又可以查詢其他上游 DNS 服務器。 ## DNS 安全嗎? DNS 本身很快但不安全。 DNS 請求未加密,容易受到“中間人”攻擊。例如,咖啡店互聯網連接可以輕易地破壞您的 DNS 請求并發回特定域的不同 IP 地址 ## 如何連接到 TCP 服務器(例如 Web 服務器?) TODO 連接到遠程計算機需要三個基本系統調用: ``` getaddrinfo -- Determine the remote addresses of a remote host socket -- Create a socket connect -- Connect to the remote host using the socket and address information ``` `getaddrinfo`調用成功,創建`addrinfo`結構的鏈接列表,并將給定指針設置為指向第一個。 套接字調用創建一個傳出套接字并返回一個描述符(有時稱為“文件描述符”),可以與`read`和`write`等一起使用。在這種意義上,它是`open`的網絡模擬打開文件流 - 除了我們尚未將套接字連接到任何東西! 最后,connect 調用嘗試連接到遠程計算機。我們傳遞原始套接字描述符以及存儲在 addrinfo 結構中的套接字地址信息。存在不同種類的套接字地址結構(例如,IPv4 與 IPv6),其可能需要更多存儲器。因此,除了傳遞指針外,還傳遞了結構的大小: ```c // Pull out the socket address info from the addrinfo struct: connect(sockfd, p->ai_addr, p->ai_addrlen) ``` ## 如何釋放為 addrinfo 結構的鏈表分配的內存? 作為最頂層`addrinfo`結構上的清理代碼調用`freeaddrinfo`的一部分: ```c void freeaddrinfo(struct addrinfo *ai); ``` ## 如果 getaddrinfo 失敗,我可以用`strerror`打印出錯誤嗎? 沒有。`getaddrinfo`的錯誤處理有點不同: * 返回值 _ 是 _ 的錯誤代碼(即不使用`errno`) * 使用`gai_strerror`獲取等效的短英文錯誤文本: ```c int result = getaddrinfo(...); if(result) { const char *mesg = gai_strerror(result); ... } ``` ## 我可以只請求 IPv4 或 IPv6 連接嗎?僅 TCP? 是!使用傳遞給`getaddrinfo`的 addrinfo 結構來定義您想要的連接類型。 例如,要通過 IPv6 指定基于流的協議: ```c struct addrinfo hints; memset(hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; // Only want IPv6 (use AF_INET for IPv4) hints.ai_socktype = SOCK_STREAM; // Only want stream-based connection ``` ## 那些使用`gethostbyname`的代碼示例呢? 舊函數`gethostbyname`已棄用;這是將主機名轉換為 IP 地址的舊方法。端口地址仍需要使用 htons 功能手動設置。使用較新的`getaddrinfo`編寫支持 IPv4 和 IPv6 的代碼要容易得多 ## 這很容易!? 是的,不是。創建一個簡單的 TCP 客戶端很容易 - 但網絡通信提供了許多不同的抽象級別,并且可以在每個抽象級別設置幾個屬性和選項(例如我們沒有談到可以操作選項的`setsockopt`插座)。有關詳細信息,請參閱[指南](http://www.beej.us/guide/bgnet/output/html/multipage/getaddrinfoman.html)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看