【问题标题】:Manually specify which network interface to send data手动指定要发送数据的网络接口
【发布时间】:2014-12-04 09:51:46
【问题描述】:

我已经实现了一个通过 tcp 套接字发送和接收数据的服务。现在我的机器上有两个网络接口,我应该通过两个网络运行服务。

如何指定发送数据的网络接口? (使用 Boost::asio 或传统的 Berkeley 套接字,或使用系统调用动态更改内核的路由表)

【问题讨论】:

  • 如果不指定任何内容会怎样?
  • @egur 从特定子网发送的请求的响应将被发送回错误的子网。
  • 这强烈暗示了错误的网络配置。修复您的网络配置,您无需明确指定。 Monkeypatching 路由表是顺便说一句。由于内核的缓冲,这不是一个选项。
  • 听起来是个糟糕的设置。如果禁用其中一个适配器会发生什么?另外,你应该在super user 上问这个,而不是堆栈溢出。
  • 我也不懂。只要数据到达那里,为什么走哪条路线很重要?

标签: c++ c sockets network-programming boost-asio


【解决方案1】:

我不了解 Boost,但一般来说,如果您想使用特定接口发送/接收,则需要 bind() 到该接口的 IP 地址的套接字,或者在某些平台上您可以使用 @987654322 @ 代替。

【讨论】:

  • 那只会接收来自指定地址的连接。
  • 为什么这被否决了?在特定网络上发送/接收 TCP 数据的唯一方法是将 TCP 套接字绑定到 特定 NIC/接口。进行出站连接时,必须先调用bind()setsockopt(SO_BINDTODEVICE),然后再调用connect()。接受入站连接时,它会自动绑定到用于接受它的任何 NIC/接口。你可以bind()/setsockopt(SO_BINDTODEVICE)一个监听套接字到一个特定的网卡/接口,或者你可以让它绑定到所有可用的网卡/接口,它会告诉你哪个接受了每个连接。
  • 我没有投反对票,但bind()SO_BINDTODEVICE 不是同义词。当一个套接字bind()s 到一个特定地址时,该套接字将只接收发往该地址的数据包,而传输的数据包将使用该地址作为它们的源地址。内核仍然可以通过与地址无关的接口路由数据包。另一方面,当一个套接字使用SO_BINDTODEVICE时,任何发送到该套接字的数据都会从关联的接口出去,并且通过该套接字接收到的任何数据都保证已经到达了关联的接口。
  • 我提到两者是因为 Windows 不支持SO_BINDTODEVICE,因此绑定到 IP 也绑定到特定接口,但其他一些平台会单独绑定到 IP 和绑定到接口。因此,可能必须在同时支持两者的平台上同时进行。
  • 我强调了区别,因为我将答案解释为建议在支持SO_BINDTODEVICE 的平台上,可以使用bind()SO_BINDTODEVICE 并获得相同的结果。在 Windows 上,绑定到 IP 将绑定到关联的接口,并且接口的 weakhostsend 配置控制路由(当套接字绑定到地址时,默认为您在支持强主机模型的系统上描述的行为)。跨度>
【解决方案2】:

你试过了吗,创建一个绑定到 0.0.0.0 的套接字来接收来自所有接口的数据包。然后为每个接口创建一个套接字用于发送数据包。这里的关键是设置 REUSEADDRSS 选项,以便用于发送的套接字可以绑定到每个接口的地址并共享一个接收数据包的相同端口。

如果您正在处理 TCP,则已建立的连接将准备好绑定到特定接口。您将无法通过其他接口发送到该连接。

【讨论】:

    猜你喜欢
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    • 2016-05-21
    • 2012-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多