2012-01-03 22 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可以相互通信。

相关问题