ruby - 绑定(bind)到 ruby​​ 中的网络接口(interface)

标签 ruby

我正在尝试在 Linux 的不同网络接口(interface)上的 ruby​​ 应用程序中打开多个套接字。例如,假设我有 IP 为 192.168.1.2 的接口(interface) eth0 和 IP 地址为 10.0.0.2 的接口(interface) wlan0。我想同时连接到服务器,每个接口(interface)上都有一个套接字。我认为绑定(bind)到这些接口(interface)的 IP 地址会起作用,但事实似乎并非如此。在 wireshark 中,当我绑定(bind)到 wlan0 的 IP 时,我成功地看到 SYN 数据包使用正确的源 IP 发送,但是 wireshark 在 eth0 上看到它们并且套接字从未打开。

Ruby 版本:ruby 1.9.3p194(2012-04-20 修订版 35410)[x86_64-linux]

这是我当前的代码。我还尝试了在 Socket 的 ruby​​-doc 页面上记录的 Addrinfo 方法,结果相同。

require 'socket'

ip = "192.168.1.2" # IP of internal interface
port = 8000
server = "" # IP of the server I'm trying to connect to goes here

lhost = Socket.pack_sockaddr_in(0, ip)
rhost = Socket.pack_sockaddr_in(port, server)
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
socket.bind(lhost)
socket.connect(rhost)

感谢您的帮助!

最佳答案

解决方案是基于源的路由

我能够弄清楚,并认为我应该留下我的答案,以防其他人在路上遇到这个问题。

我需要做的是基于源的路由。一般的想法是创建两个路由表,一个在一个接口(interface)上强制流量,一个在另一个接口(interface)上强制流量,并有一个 ip 规则,该规则根据源 IP 地址使用适当的路由表。我是这样设置的:

创建表格

首先,我必须编辑 /etc/iproute2/rt_tables 以添加以下行:

128    multiplex0
129    multiplex1

这创建了两个 ID 为 128129 的路由表,分别称为 multiplex0multiplex1

向表中添加路由

接下来我为这些表创建了如下规则:

ip route add default via 10.0.2.2 table multiplex0 
ip route add default via 192.168.1.1 table multiplex1

这些命令指定在路由表中使用的默认网关。我的 10.0/16 网络的默认网关是 10.0.2.2,我的 192.168.1/24 网络的默认网关是 192.168.1.1。

如果两个网络有相同的默认网关怎么办?

我相信如果您的网络具有相同的默认网关,您可以将 dev eth0(或任何您的接口(interface))添加到上述命令以指定接口(interface),但我尚未对此进行测试。当我了解更多时,我会进行编辑。

编辑:我已经对此进行了测试,它确实有效。如果您在路由中指定接口(interface),则两条路由可以具有相同的默认网关。

基于源的规则

接下来我需要创建规则来使用这些表:

ip rule add from 10.0.0.0/16 table multiplex0
ip rule add from 192.168.1.1/24 table multiplex1

这些规则表明,源 IP 在 10.0/16 范围内的任何数据包都应根据 multiplex0 中的规则进行路由,而源 IP 在 192.168.1/24 范围内的任何数据包都应使用 multiplex1。当数据包使用这些表时,它们被定向到适当的网关和相应的接口(interface)。中提琴!

编辑:在这一步中只指定网络接口(interface)的 IP 会更准确!例如,如果两个接口(interface)都在 192.168.1/24 网络上,则这是必要的。

刷新缓存

最后,我发布了 ip route flush cache 使一切生效,并使用上面的 ruby​​ 代码,我能够在正确的接口(interface)上打开我的两个套接字到同一个公共(public)可路由主机。

关于ruby - 绑定(bind)到 ruby​​ 中的网络接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16970361/

相关文章:

ruby-on-rails - rvm rack ruby​​ 错误已经初始化常量 WFKV_

ruby - 无法将提交推送到 heroku

mysql - 充当 Taggable On taggable_id 增量如此之快

ruby - 安装 RVM 时出错

javascript - 我们如何在 ruby​​ on Rails 文档中使用 d3.js?

mysql - 如何知道列的数据类型?

ruby-on-rails - 加载错误 : Could not open library 'lzo2' : lzo2: cannot open shared object file: No such file or directory

ruby - 是否有处理跨框架身份验证的标准方法?

ruby - 在 Ruby 中修改缓冲区字节的快速可靠技术?

mysql - 如何将 ruby​​ on Rails 应用程序导入到另一台计算机