2012-01-03 28 views
10

使用socket編程API(例如,插座(),連接(),接受()......),我怎麼能知道,如果一個TCP連接是兩個過程之間的同一臺機器上?說,我有套接字文件描述符,和遠程IP。我可以簡單地檢查遠程IP是否爲127.0.0.1?如何知道TCP連接是否在同一臺機器上的兩個進程之間?

+1

你可以嘗試調用'getsockname()'和'getpeername()'同一插座上,然後比較返回的地址。 – 2012-01-03 21:31:48

+0

在同一臺計算機上禁止多個網絡設備,您是否可以檢查連接每端的MAC地址,並查看它們是否相同? – abelenky 2012-01-03 21:42:24

+0

通常沒有MAC報頭,因此沒有MAC地址,在環回上使用。 – 2012-01-03 21:52:53

回答

2

這裏是我使用的方法。我們的想法是嘗試將偵聽器綁定到該IP地址,並使用失敗/成功代碼來決定地址是否爲本地。

我不是說這是特別有效的,但它應該是相當可靠的,而我的應用程序是合適的。

#include <sys/socket.h> 
#include <errno.h> 
/* ...probably need some other headers I am forgetting... */ 

int 
is_local(const struct sockaddr *addr, socklen_t addr_len) 
{ 
    const char *func = "is_local()"; 
    int result = 0; 

    int tmp = socket(addr->sa_family, SOCK_STREAM, 0); 
    if (tmp < 0) { 
     printf("%s: socket(%d,SOCK_STREAM,0) failed, errno %d\n", 
       func, addr->sa_family); 

     goto out; 
    } 

    /* If bind() succeeds, or if it fails because the address is in 
     use, then the address must be local to this system. */ 
    if (bind(tmp, addr, addr_len) < 0) { 
     if (errno == EADDRINUSE) 
      result = 1; 
     else if (errno == EADDRNOTAVAIL) 
      ; /* do nothing; address is remote */ 
     else 
      printf("%s: bind() unexpected error %d\n", func, errno); 
    } 
    else { 
     result = 1; 
    } 

    close(tmp); 

out: 
    return result; 
} 

你這樣稱呼它:

struct sockaddr_storage client_addr; 
socklen_t client_addr_len = sizeof(client_addr); 
int fd = accept(listener, &client_addr, &client_addr_len); 

if (is_local((struct sockaddr *)&client_addr, client_addr_len)) 
    /* peer is local */ 
+0

我喜歡這種方法! – flyingbin 2012-01-03 22:23:32

7

有沒有確定這真的是可靠的方法 - 您可以連接到使用全局路由的IP地址(即本地進程可以使用比127.0.0.1其它IPS)本地進程。如果您處於虛擬化環境中,還可以在同一物理硬件上的不同虛擬機中運行進程。

但是請注意,如果遠程IP(經由getpeername)或本地IP(通過getsockname)與127(包括127.0.0.1)開始,然後這的確是一個本地連接;但是,如果它是一對不同的地址,則不能排除可能爲爲本地連接的可能性。

2

如果你已經有了遠程IP地址,你可以檢查它是否是環回地址,或者它是否是主機的IP地址,因爲正如cnicutar指出的那樣,它不必經過環回地址是本地連接。

3

使用getsockname()getpeername()中檢索與連接相關的兩個IP地址,然後使用gethostname()gethostbyname()(或其他特定平臺的API,如GetAdaptersInfo()GetAdapterAddresses()在Windows上),確定屬於本地計算機的IP地址,然後您可以將連接IP與本地機器IP進行比較,看它們是否匹配。一臺機器可以分配多個IP,並且同一臺機器上的多個IP可以相互通信。

相關問題