在POSIX C中获取自己的外部IP地址

3
我希望获得自己的IP地址,以便将该信息发布到点对点网络中。在POSIX/C中,我们有getaddrinfo(NULL, ...),但它似乎总是返回INADDR_ANYINADDR_LOOPBACK,这对我没有用处。
有什么建议吗?
6个回答

5

其中一个问题是,即使您获得了本地IP地址,由于NAT的混乱(这种情况非常普遍),互联网上看到的IP地址可能会有所不同。使用IPv6可能会解决此问题,但现在可能不是您的选择。

要获取公共 IP地址,您需要使用专门用于此目的的协议,例如STUNRFC 5389)。有公共STUN服务器和已经存在的C中的STUN客户端

所有的点对点程序都有类似的问题,所以要学习其他人正在做什么,我强烈推荐阅读RFC 5128,“网络地址转换器(NAT)跨点对点(P2P)通信的状态”


1

通过公共地址,你是在说一个地址,你的应用程序同行可以用它联系你。唯一可靠的方法是连接到已知的“外部”同行,并让它将你的地址发送回给你。


http://checkip.dyndns.org将始终返回您当前有效的外部IP地址。 - Chris Thompson

1

虽然我不想让事情变得更加复杂,但我应该指出一台计算机可以有多个IP地址。通常每个网络卡都会有一个。

更具体的询问方式是“当我连接到foo.com.org时,如何找到将用作源地址的IP地址”。我喜欢bortzmeyer的答案:)


0
创建一个UDP套接字,绑定到INADDR_ANY,连接到互联网上的某个地址,然后使用getsockname()函数在套接字上查找它被分配的地址。
另一个好的解决方案是,如果网络协议支持,只需询问引导对等方他们认为你的IP是什么。这会自动处理NAT。

尝试过你的第一种方法。使用UDP套接字,它会给我返回0.0.0.0(INADDR_ANY)。我可能会考虑第二种方法。 - Nick
"询问您的引导同行他们认为您的IP是什么"时存在几个陷阱。最好避免重复发明轮子,使用现有的协议,如STUN。 - bortzmeyer

0
你有检查返回结构体中的 ai_next 字段吗? getaddrinfo() 返回地址链表。

但是这似乎总是返回 INADDR_ANY 或 INADDR_LOOPBACK。我正在遍历列表... 所以是的。 - Nick

-1
如果您知道主机名,可以使用 gethostbyname 获取 IP 地址。

gethostbyname已经被废弃多年(已被getaddrinfo替代)。它存在许多问题,其中之一是仅支持IPv4。 - bortzmeyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接