0

我在一个 debian 6 机器上有几个物理网络接口,每个都有不同的子网 IP 地址。其中两个接口连接到交换集线器,因此它们可以相互通信。我想在 2 个接口之间建立 TCP 连接。

这就是我所做的:我首先得到一个 SOCK_STREAM 套接字。然后我使用 setsockopt(..., SO_BINDTODEVICE,...) 将套接字绑定到特定接口 eth4。然后我设置了一个 sockaddr_in 结构并使用该接口(eth4)的端口和地址填充它。然后我调用 bind() 将该本地地址/端口绑定到套接字。然后我做一个listen(),然后是一个accept()。这会阻止等待传入的连接请求。此时我可以做一个 netstat,它完全显示了我的预期,即套接字确实处于 LISTEN 状态,并且本地地址正确显示了 eth4 地址和端口。

然后在一个单独的程序中,我有一个获取套接字的例程,然后 setsockopt(..., SO_BINDTODEVICE,...) 将套接字绑定到不同的接口 eth5。然后,我使用与 eth4 接口相同的端口号和 eth4 接口的地址设置了一个 sockaddr_in 结构。然后我做一个连接()。一切顺利,连接成功,我的日志确实显示这两个进程确实与这个 TCP 连接相连。

但是当我执行 netstat 时,它显示 2 个 PID/程序已连接,但本地地址和外部地址都显示来自 eth4 的相同地址,即使我专门将连接端绑定到 eth5 的地址。

所以,我的问题是为什么 netstat 为连接的两端显示相同的地址?

我能想到的唯一解释是内核识别出连接目标地址实际上是本地的,然后忽略了我所做的 SO_BINDTODEVICE 绑定,并使 TCP 连接成为内部而不是实际走出 eth5 连接到 eth4。

如果这是正确的,那么我该如何在同一个 linux 机器上的 2 个独立接口之间建立 TCP 连接,但实际上是在外部而不是内部?

-安德烈斯

4

1 回答 1

0

您可以尝试bind在之前调用connect客户端套接字,以将其与您要使用的传出接口 (eth5) 的特定 IP 地址相关联(端口可以设置为 0,因为在这种情况下它对客户端无关紧要)。这种方法似乎是使用SO_BINDTODEVICE选项的替代方法。

我发现一篇文章提供了几种设置此选项的方法(http://stackoverflow.com/a/6566111/276274)。第一个是将字符串传递给setsockopt设备名称,另一个是通过struct ifreq填充接口索引传递 via ioctl。您可以尝试使用接口索引探索第二个。

另一个潜在的问题来源可能是设置此选项似乎需要 root 权限。

如果您可以在设置选项的位置发布代码片段,这可能会有所帮助。

于 2012-08-07T15:24:41.483 回答