簡體   English   中英

C套接字編程:與getaddrinfo()綁定並獲取設備IP服務器可用

[英]C socket programming: binding with getaddrinfo() and get device IP server is available

我正在使用getaddrinfo()創建被動服務器套接字(如我所讀的“現代”方法)。 使用這種方法並在提示中指定:AI_PASSIVE,AF_UNSPEC,sock_type我遍歷如下結果:

 for(ai_ptr = addrinfo_res; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)

然后創建套接字並綁定到第一個addrinfo_res中找到的地址。

 bind(ps_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen)

我如何知道我的服務器在局域網上可用的哪個地址(不是0.0.0.0)?

我在下面嘗試了此代碼,以查找它們上的所有接口和IP地址:

 // linked list of structures describing
    // the network interfaces of the local system
    struct ifaddrs *ifaddr, *ifa;
    int n, gai_err;

    if(getifaddrs(&ifaddr) == FAILURE) {
        fprintf(stderr, "getifaddrs: %s\n", strerror(errno));
        return FAILURE;
    }

    // walk through linked list
    for(ifa = ifaddr, n=0; ifa != NULL; ifa = ifa->ifa_next, n++) {

        if(ifa->ifa_addr == NULL)
            continue;

        int family = ifa->ifa_addr->sa_family;

        // display interface name, family
        printf("%-8s %s (%d)\n", ifa->ifa_name,
               (family == AF_INET) ? "AF_INET" :
               (family == AF_INET6) ? "AF_INET6" : "???",
               family);

        // for an AF_INET* interface addresses, display the address
        if(family == AF_INET || family == AF_INET6) {

            char host[NI_MAXHOST];

            if( (gai_err = getnameinfo(ifa->ifa_addr,
                        (family == AF_INET) ? sizeof(struct sockaddr_in) :
                                              sizeof(struct sockaddr_in6),
                        host, NI_MAXHOST,
                        NULL, 0, NI_NUMERICHOST)) != 0) {
                fprintf(stderr, "getnameinfo: %s\n", gai_strerror(gai_err));
            }

            printf("\t\t address: <%s>\n", host);
        }
    }

    freeifaddrs(ifaddr);
    return SUCCESS;

但是如何確定我將返回(打印)客戶端可以連接到的合適IP地址?

我有這樣的結果:

lo0      ??? (18)
lo0      AF_INET (2)
         address: <127.0.0.1>
lo0      AF_INET6 (30)
         address: <::1>
lo0      AF_INET6 (30)
         address: <fe80::1%lo0>
gif0     ??? (18)
stf0     ??? (18)
en0      ??? (18)
en0      AF_INET6 (30)
         address: <fe80::1088:e458:89a7:7ee9%en0>
en0      AF_INET (2)
         address: <192.168.8.102>
en1      ??? (18)
bridge0  ??? (18)
p2p0     ??? (18)
awdl0    ??? (18)
awdl0    AF_INET6 (30)
         address: <fe80::dce1:4eff:fef8:f3bd%awdl0>
utun0    ??? (18)
utun0    AF_INET6 (30)
         address: <fe80::695f:8478:f380:9efb%utun0>

當我測試服務器僅在192.168.8.102或IPv6 :: ffff:192.168.102上可用時。 但是在第二個en0 AF_INET6 IP地址fe80 :: 1088:e458:89a7:7ee9上。 如何確保當其他人在具有不同IP地址和接口的另一台計算機上使用該程序時(例如不是en0而是eth0?),我將可以返回服務器可用的正確IP地址,以便他/她知道在哪個IP上它可以從客戶端程序連接? 在此處輸入圖片說明

您不能確定,因為任何系統都可以具有具有不同網絡和地址的多個接口。 甚至返回的路由也不必與到您的系統的路由相同。

此外,由於客戶端和服務器之間任何地方的NAT,客戶端可能必須連接到不同的地址和端口。

您可以使用IP_PKTINFO套接字選項從recvmsg中獲取地址,以查看消息的目標地址,但是同樣,這可能已經在網絡級別進行了轉換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM