没有真正可靠的方法来确定这一点 - 您可以使用全局路由的IP地址连接到本地进程(即,本地进程可以使用除以外的IP 127.0.0.1).如果您处于虚拟化环境中,那么进程也可以在同一物理硬件上的不同虚拟机中运行.
但是,请注意,如果远程IP(通过getpeername)或本地IP(通过getsockname)以127(包括127.0.0.1)开头,那么它确实是本地连接; 但是,如果它是一对不同的地址,则不能排除它可能是本地连接的可能性.
这是我使用的方法。这个想法是尝试将侦听器绑定到该 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;
}
Run Code Online (Sandbox Code Playgroud)
你这样称呼它:
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 */
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1231 次 |
| 最近记录: |