提供指定 NIC、确定子网上 IP 的选项的最佳方式?
我正在编写一个 C 库,其中涉及告诉子网上的其他计算机向我发送消息。因此我必须向他们公布我的IP地址。该库应该可以在 Linux、OS X 和 Windows 上运行。目前我主要考虑的是 POSIX 层。
鉴于一台计算机可以有多个地址(例如,如果它有多个网络接口),
查找我的默认 IP 地址的最佳方式是什么(例如,以最简单、最常见的方式)目前,我正在使用 getifaddrs 循环访问系统网卡并返回第一个关联的网卡(优先选择非环回),但我认为这可能不够。
什么是一个好的 API,可以让库的用户选择在哪个接口上发送?我假设对计算机的 NIC 和 IP 进行某种枚举,然后按名称选择 NIC 并查找其 IP。但从用户的角度来看,这似乎相当复杂。给定子网上另一台计算机的 IP,也许有某种方法可以通过网络掩码确定系统到子网的路由?不过,我不知道如何做到这一点。
对于 2,我们最终可以假设可能有一个 GUI 或命令行选项允许用户选择 NIC,但总的来说,我想让它尽可能简单地自动告诉其他计算机如何将 UDP 消息定向到它。
任何意见表示赞赏,谢谢!
I am writing a C library which involves telling other computers on the subnet to send me messages. Therefore I must announce to them my IP address. This library should work on Linux, OS X and Windows. Currently I'm thinking mostly about the POSIX layer.
Given that a computer can have more than one address (for example if it has more than one network interface),
What's the best way to find my default IP address (e.g. in the simplest most common case of a computer with a single connection to the subnet.) Currently I'm cycling through the system NICs using
getifaddrs
and returning the first one that is associated (with preference to non-loopback), but I think this is probably not adequate.What would be a good API for allowing users of the library to choose which interface to send on? I assume some sort of enumeration of the NICs and IPs of the computer, then selecting the NIC by name and finding its IP. This seems pretty complicated from a user standpoint though. Perhaps some way to determine the system's route to the subnet by netmask, given the IP of another computer on the subnet? I have little idea how to do that, though.
For 2, we can eventually assume there may be a GUI or command-line option allowing users to choose the NIC, but in general I want to make it as easy as possible for it to automatically tell other computers how to direct UDP messages to it.
Any opinions appreciated, thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您已经使用 IP 与其他计算机进行通信,则数据包将已经宣布一个返回地址,远端可以使用该地址来确定其消息应发送到的位置。
尝试推断要使用的正确接口地址并将其嵌入到消息中并不是一个好主意,原因有四个(可能更多)。首先,您最终将重新实现操作系统为弄清楚如何路由出站数据包而执行的所有逻辑。其次,如果路由表在您做出决定的时间和您实际需要连接到其他计算机并告诉它们将流量发送到哪里的时间之间发生变化,那么您将向它们发送错误的地址。第三,目标计算机可能并不总是位于同一子网上,在这种情况下,所有接口都不会匹配。第四,如果数据包在您和目的地之间经历任何形式的重写(例如 NAT),执行此操作的软件将不知道它需要深入到您的数据包中,并且远端的系统将不会使用正确的地址。
If you're already communicating with other computers using IP, the packets will already be announcing a return address that the far end can use to determine where its messages should go.
Attempting to deduce the right interface address to use and embedding it in a message isn't a good idea for four reasons (probably more). First, you're going to end up reimplementing all of the logic your OS does to figure out how to route outbound packets. Second, if the routing table changes between the time you make that decision and the time you actually need to connect to the other computers and tell them where to send traffic, you'll be sending them the wrong address. Third, the destination computers may not always be on the same subnet, in which case none of the interfaces will match. Fourth, if the packets undergo any form of rewriting (e.g., NAT) between you and the destination, the software doing it will have no idea that it needs to dive into your packets and the systems at the far end won't be using the right address.
1. 默认IP地址
主机的默认IP地址并不存在。一般来说,尽管大多数主机都配置了默认路由,但操作系统会在找不到时决定使用该默认路由,方法是结合数据包的目标 IP 地址(发送数据包的另一个接口)查看其路由表。该接口将有一个 IP 地址,我想您可以将其视为默认 IP 地址。但是,在多宿主主机的情况下,所使用的源 IP 地址取决于 ip 标头中的目标 IP 地址,并且由操作系统结合路由表计算得出。这就是为什么没有默认 IP 地址之类的东西。即使您确实使用了与默认路由关联的 IP 地址,并告诉其他主机的用户该地址,也不能保证从他们的主机到您的主机的数据包一定会到达,因为他们的主机可能位于不同的子网中(即无法通过默认路由访问)。
2. 路由API:
这听起来像是您想在应用程序级别实现某种路由。这个逻辑是操作系统在决定将数据包发送到哪里时处理的,所以我认为你不需要实现这个。
3. 广告服务和 mDNS:
如果您知道其他主机位于同一子网上,请查看 mDNS(多播 dns)。这将允许您通告您的主机拥有的服务(IP 地址、端口号),并且联系同一多播组的其他主机可以发现此信息。 avahi 是 mDNS 的一个实现。
1. Default ip address
There isn't really such a thing as a default ip address of a host. In general though most hosts are configured with a default route that the OS decides to use if it can't find, by looking at it's routing table in conjunction with the destination ip address of the packet, another interface to send a packet out on. This interface will have an ip address and I suppose you could consider it to be the default ip address. But, in the case of a multi-homed host the source ip address that is used depends on the destination ip address in the ip header and that's worked out by the operating system in conjuction with the routing table. Which is why there's no such thing as a default ip address. And even if you did use the ip address associated with the default route, and told the users of the other hosts about this address there's no gaurantee that a packet from their end to your host will arrive because their hosts might be on a different subnet (i.e. not accessable via the default route).
2. Routing API:
This sounds like you want to implement some sort of routing at the application level. This logic is something the operating system handles when deciding where to send a packet, so I don't think you need to implement this.
3. Advertizing services and mDNS:
If you know that the other hosts are on the same subnet look into mDNS (mulitcast dns). This will allow you to advertize services (ip address, port number) that your host has and other hosts that contact the same multicast group can discover this information. avahi is an implementation of mDNS.