【问题标题】:Best way to provide options for specifying NIC, determining IP on subnet?提供指定 NIC 选项、确定子网 IP 的最佳方式?
【发布时间】:2010-10-06 15:53:18
【问题描述】:

我正在编写一个 C 库,其中涉及告诉子网上的其他计算机向我发送消息。因此我必须向他们宣布我的 IP 地址。这个库应该可以在 Linux、OS X 和 Windows 上运行。目前我主要考虑 POSIX 层。

鉴于一台计算机可以有多个地址(例如,如果它有多个网络接口),

  1. 找到我的默认 IP 地址的最佳方法是什么(例如,在最简单的最常见的计算机与子网连接的情况下。)目前我正在循环浏览系统网卡使用getifaddrs 并返回第一个关联的网卡(优先于非环回),但我认为这可能还不够。

  2. 什么是允许库用户选择发送接口的好 API?我假设对计算机的 NIC 和 IP 进行某种枚举,然后按名称选择 NIC 并找到其 IP。不过,从用户的角度来看,这似乎相当复杂。给定子网上另一台计算机的 IP,也许有某种方法可以通过网络掩码确定系统到子网的路由?不过,我不知道该怎么做。

对于 2,我们最终可以假设可能有一个 GUI 或命令行选项允许用户选择 NIC,但总的来说,我想让它尽可能简单地自动告诉其他计算机如何引导 UDP给它发消息。

任何意见表示赞赏,谢谢!

【问题讨论】:

    标签: c networking posix


    【解决方案1】:

    如果您已经在使用 IP 与其他计算机通信,则数据包将已经宣布返回地址,远端可以使用该地址来确定其消息应该去哪里。

    尝试推断要使用的正确接口地址并将其嵌入到消息中并不是一个好主意,原因有四个(可能更多)。首先,您最终将重新实现您的操作系统所做的所有逻辑,以弄清楚如何路由出站数据包。其次,如果路由表在您做出决定的时间与您实际需要连接到其他计算机并告诉他们将流量发送到哪里的时间之间发生变化,那么您将向他们发送错误的地址。第三,目标计算机可能并不总是在同一个子网上,在这种情况下,没有一个接口会匹配。第四,如果数据包在您和目的地之间经历了任何形式的重写(例如,NAT),执行此操作的软件将不知道它需要深入您的数据包,并且远端的系统不会使用正确的地址。

    【讨论】:

    • 好的,谢谢,我原则上同意您的回答,除了您的第一点:“您最终将重新实现您的操作系统为弄清楚如何路由出站数据包而执行的所有逻辑。”实际上我是在问是否有办法让操作系统为我执行此操作并让我查询它的决定,而不是我如何自己重新实现它。
    • 啊,好的。我读到您的问题是询问如何在不建立连接的情况下事先弄清楚,以便您可以向您的用户推荐一个。我能想到的唯一方法是实际建立连接,然后致电getsockname() 看看它是如何掉线的。到那时,远端已经可以确定近端的 IP,所以发送它是一个有争议的问题。唯一的另一种方法是查询路由表(我 97% 肯定不能移植)并手动计算源接口。
    【解决方案2】:

    1。默认ip地址

    实际上并没有主机的默认 IP 地址这样的东西。通常,尽管大多数主机都配置了默认路由,如果找不到,操作系统会决定使用该路由,通过查看它的路由表以及数据包的目标 IP 地址,另一个接口发送数据包。这个接口会有一个IP地址,我想你可以认为它是默认的IP地址。但是,在多宿主主机的情况下,使用的源 IP 地址取决于 ip 标头中的目标 IP 地址,并且由操作系统结合路由表计算出来。这就是为什么没有默认 IP 地址这样的东西的原因。即使您确实使用了与默认路由关联的 ip 地址,并告诉其他主机的用户该地址,也无法保证从他们端到您的主机的数据包将到达,因为他们的主机可能位于不同的子网(即无法通过默认路由访问)。

    2。路由 API:

    这听起来像是您想在应用程序级别实现某种路由。这个逻辑是操作系统在决定向哪里发送数据包时处理的,所以我认为你不需要实现这个。

    3。广告服务和 mDNS:

    如果您知道其他主机在同一子网中,请查看 mDNS(多播 dns)。这将允许您宣传您的主机拥有的服务(IP 地址、端口号),并且与同一多播组联系的其他主机可以发现此信息。 avahi 是 mDNS 的实现。

    【讨论】:

    • “这听起来像是您想在应用程序级别实现某种路由。”并不真地。也许我应该在问题中说出来,但我想在多播端口上宣布我的 IP 地址是什么,以便其他客户端可以直接向我发送消息。
    • @Steve:如果是这种情况,请查看多播 dns。它允许主机宣布 IP 地址。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    • 2018-04-03
    • 2016-01-09
    相关资源
    最近更新 更多