2011-03-23 157 views
1

我的問題是:如何獲取接受的入站套接字的IP地址?

服務器將創建一個套接字,綁定到給定的端口和地址= INADDR_ANY。 ()& accept()新的連接。然後,我們可以從accept()獲取客戶端的IP地址

現在,我想知道服務器的IP地址,因爲服務器的主機上有

多個NIC。

如何知道接受的入站套接字來自哪個網絡接口的ip地址?

我試過getsockname,它給了我端口號,但ip是全零。

更新:這裏是代碼:

Server.c(頭文件被刪除)

int main(void) 
{ 

    struct sockaddr_in stSockAddr; 
    int res, addr_len, SocketFD, ConnectFD; 

    struct sockaddr_in addr; 

    SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 

    if(-1 == SocketFD) 
    { 
     perror("can not create socket"); 
     //exit(EXIT_FAILURE); 
     return -1; 
    } 

    memset(&stSockAddr, 0, sizeof stSockAddr); 
    stSockAddr.sin_family = AF_INET; 
    stSockAddr.sin_port = htons(49335); 
    stSockAddr.sin_addr.s_addr = INADDR_ANY; 

    if(-1 == bind(SocketFD,(struct sockaddr *)&stSockAddr, sizeof stSockAddr)) 
    { 
     perror("error bind failed"); 
     close(SocketFD); 
    return -1; 
    } 


    printf("going to listen!\n"); 
    if(-1 == listen(SocketFD, 10)) 
    { 
     perror("error listen failed"); 
     close(SocketFD); 
     //exit(EXIT_FAILURE); 
     return -1; 
    } 

    ConnectFD = accept(SocketFD, NULL, NULL); 

     if(0 > ConnectFD) 
     { 
       perror("error accept failed"); 
       close(SocketFD); 
       //exit(EXIT_FAILURE); 
       return -1; 
     } 

    addr.sin_family = AF_INET; 
    res = getsockname (ConnectFD, (struct sockaddr *)&addr, &addr_len); 
    // if you remove the following comment, that means, if you call 
    // two times of getsockname, the result will be correct. 
    //res = getsockname (ConnectFD, (struct sockaddr *)&addr, &addr_len); 

    printf("addr:%x\n", addr.sin_addr.s_addr); 

    while(1) { 
     if (getchar() == 'q') 
         break; 
    } 

    close(ConnectFD); 
    close(SocketFD); 
    return 0; 
} 

下面是client.c:

int main(void) 
{ 

    struct sockaddr_in stSockAddr; 

    int Res; 

    int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 

    if (-1 == SocketFD) 
    { 
     perror("cannot create socket"); 
     exit(EXIT_FAILURE); 
    } 

    memset(&stSockAddr, 0, sizeof stSockAddr); 

    stSockAddr.sin_family = AF_INET; 
    stSockAddr.sin_port = htons(49335); 
    Res = inet_pton(AF_INET, "192.168.1.102", &stSockAddr.sin_addr); 

    if (0 > Res) 
    { 
     perror("error: first parameter is not a valid address family"); 
     close(SocketFD); 
     exit(EXIT_FAILURE); 
    } 
    else if (0 == Res) 
    { 
     perror("char string (second parameter does not contain valid ipaddress"); 
     close(SocketFD); 
     exit(EXIT_FAILURE); 
    } 

    if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof stSockAddr)) 
    { 
     perror("connect failed"); 
     close(SocketFD); 
     exit(EXIT_FAILURE); 
    } 

    /* perform read write operations ... */ 
    printf("client sockfd is successful\n"); 

     while(1) { 

      if (getchar() == 'q') 
       break; 

     } 


    shutdown(SocketFD, SHUT_RDWR); 

    close(SocketFD); 
    return 0; 
} 
+0

請簡單編輯您的問題以提供更多信息。嚴格保留答案以解決您的問題。您也可以在您的問題下使用評論功能,或者使用任何答案來討論已發佈的解決方案或提供說明。 – 2011-03-24 10:28:55

回答

9

使用getsockname(2)在從accept(2)返回的套接字上,而不是bind(2)返回的套接字。

6

getsockname()獲取傳遞的套接字的名稱。在本例中爲 ,您通過服務器中的 接受函數創建的套接字。 這個套接字在服務器端,所以它的名字&地址是 與服務器端相關。

,如果你想知道「誰是連接到我」 必須使用getpeername()代替getsockname。

好運

1

如果刪除了以下注釋,這意味着,如果你調用getsockname的 兩次,結果將是正確的。 res = getsockname(ConnectFD,(struct sockaddr *)& addr,& addr_len);

您必須初始化addr_len。

addr_len = sizeof(addr); 
相關問題