簡體   English   中英

為什么inet_ntop()和inet_ntoa()給出不同的結果?

[英]Why inet_ntop() and inet_ntoa() gives different result?

我正在創建UDP服務器-客戶端程序。 客戶端請求文件,如果找到,服務器將發送給客戶端。 根據Beej的網絡指南,

  • inet_ntoa()返回靜態緩沖區中的點和數字字符串,該字符串在每次調用該函數時都會被覆蓋。
  • inet_ntop()成功返回dst參數,失敗則返回NULL(並設置了errno)。

該指南提到不建議使用ntoa,因此建議使用ntop,因為它支持IPv4和IPv6。

在我的代碼上,使用函數或其他函數會得到不同的結果,我的理解是它們應該拋出相同的結果。 我有什么想念的嗎? 任何幫助將不勝感激。

碼:

    //UDP Client
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>

    #define MAXBUFLEN 1024
    #define SER_IP "176.180.226.0" 
    #define SER_PORT "1212"

    // Get port, IPv4 or IPv6:
    in_port_t get_in_port(struct sockaddr *sa){
        if (sa->sa_family == AF_INET) {
            return (((struct sockaddr_in*)sa)->sin_port);
        }
        return (((struct sockaddr_in6*)sa)->sin6_port);
    }

    int main(int argc, char *argv[]){
        int sock, rv, numbytes;
        struct addrinfo hints, *servinfo, *p;
        char buffer[MAXBUFLEN];

        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_DGRAM;

        rv = getaddrinfo(NULL, SER_PORT, &hints, &servinfo);
        if (rv != 0){
            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
            exit(1);
        }

        // Printing IP, should provide same result
        for(p = servinfo; p != NULL; p = p->ai_next) {
            char str1[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, &p->ai_addr, str1, INET_ADDRSTRLEN); 
            printf("ntop:%s\n", str1) ;
            printf("inet_ntoa:%s \n", inet_ntoa(((struct sockaddr_in *)p->ai_addr)->sin_addr));
            printf("\n");
        }

        exit(1);
    }

電流輸出:

ntop:64.80.142.0
inet_ntoa:0.0.0.0 

ntop:160.80.142.0
inet_ntoa:127.0.0.1 

根據man頁,對於AF_INET ,參數src必須指向struct in_addr (網絡字節順序)。

在您的struct addrinfo您有一個指向struct sockaddr的指針,該指針基本上是

sa_family_t sa_family;
char        sa_data[];

但是, struct sockaddr_in

sa_family_t    sin_family;
in_port_t      sin_port;
struct in_addr sin_addr;

因此,您需要更換

inet_ntop(AF_INET, &p->ai_addr, str1, INET_ADDRSTRLEN);

由任一

inet_ntop(AF_INET, &p->ai_addr->sa_data[2], str1, INET_ADDRSTRLEN);

src參數可以是&p->ai_addr->sa_data[1 << 1]以避免“幻數” 2用於計算端口號存儲的偏移量)

要么

inet_ntop(AF_INET, &((struct sockaddr_in *)p->ai_addr)->sin_addr, str1, INET_ADDRSTRLEN);

然后它將產生正確的輸出。

暫無
暫無

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

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