将套接字重新绑定到不同的接口

Posted

技术标签:

【中文标题】将套接字重新绑定到不同的接口【英文标题】:Rebind a socket to a different interface 【发布时间】:2009-05-05 18:47:47 【问题描述】:

是否有现有的 Linux/POSIX C/C++ 库或示例代码来说明如何将套接字从一个物理接口重新绑定到另一个?

例如,我在与物理连接 A 关联的套接字上进行 ping 传输,我想将该套接字重新绑定到物理连接 B 并继续在连接 B 上发送和接收 ping 数据包(经过短暂的延迟在切换期间)。

我只需要这个用于无会话协议。

谢谢

更新:

我正在尝试提供用于 PPP 和以太网设备的故障转移解决方案。

我有一个基本脚本,它可以通过使用 iptables、NAT 和路由表来完成 90% 的功能。

问题是发生故障转移时,ping 会继续在辅助连接上发送,但是它们的源 IP 来自旧连接。

我与几个从事商业路由器工作的人交谈过,他们的建议是将套接字重新绑定到辅助接口。

更新 2:

我很抱歉没有提前说明这一点。此解决方案将在路由器上运行。我无法更改 ping 程序,因为它将在客户端计算机上运行。我以 ping 为例,任何不是基于会话的连接都应该能够被切换。我在几个商业路由器上测试了这个功能,它确实有效。不幸的是,他们的软件是专有的,但是,通过各种对话和测试,我发现他们在故障转移时重新绑定了套接字。

【问题讨论】:

我可能在这里遗漏了一些东西,但是您是否尝试过关闭套接字然后绑定到另一个接口? 谢谢鸭子,我要试试看会发生什么。 【参考方案1】:

在您更新的帖子中,问题在于更改路由信息不会更改您的 ping 的源地址,它只会强制它退出第二个接口。 This answer 包含一些相关信息。

您需要更改 ping 程序。您可以使用每个接口的套接字方法,并以某种方式通知程序何时进行故障转移。或者你将不得不关闭套接字,然后绑定到第二个接口。

您可以通过多种方式获取所需的接口信息,包括使用 SIOCGIFCONF 选项调用 ioctl() 并遍历返回的结构以获取接口地址信息。

【讨论】:

我最终将 proc 参数 /proc/sys/net/ipv4/netfilter/ip_conntrack_icmp_timeout 设置为 1 以强制 icmp 数据包超时,然后将其重置为原始值。这迫使 ping 重新绑定到不同的接口。这是一个障碍,但该 NIC 的 Ralink 驱动程序不支持很多 ioctl 调用。【参考方案2】:

我不认为这是一个定义明确的操作。物理接口有不同的 MAC 地址,所以除非你有一个路由层映射它们(NAT 等),否则它们将有不同的 IP 地址。

端口由<IP addr, Port number, protocol> 的三元组标识,因此如果您的 IP 地址发生变化,端口也会发生变化。

你真的想在这里做什么?

【讨论】:

【参考方案3】:

我完全不确定您要完成什么,但我有一个猜测...您是在尝试进行某种故障转移吗?如果是这样,那么确实有办法做到这一点,但为什么不在操作系统而不是应用程序中做到这一点呢?

一方面您可以使用CARP,另一方面您可以在故障转移模式下使用接口中继/绑定(术语不同)。

【讨论】:

我看到了 CARP 和绑定,但是由于 CARP 的空间限制,我不能使用其中任何一个,不幸的是,Linux 2.6 内核没有绑定以太网和 PPP 设备。

以上是关于将套接字重新绑定到不同的接口的主要内容,如果未能解决你的问题,请参考以下文章

Java:绑定和连接方法

iOS 14 Cordova Chrome 套接字绑定不起作用

如何在linux中指定用于套接字的接口

将套接字绑定到本地主机以外的任何地址是啥意思?

无法将套接字绑定到地址

OS X 相当于 SO_BINDTODEVICE