2012-08-07 119 views
0

我在debian 6盒上有几个物理网络接口,每个接口都有不同的子网IP地址。其中两个接口连接到交换机集线器,以便它们可以相互通信。我想在两个接口之间建立一个TCP连接。为什么netstat显示错误的国外地址

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

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

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

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

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

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

-Andres

回答

0

您可以尝试connect之前调用bind的客户端套接字将它与您要使用的输出接口(eth5)的特定IP地址相关联(端口可以设置为0,因为这对客户而言是微不足道的)。这种方法似乎是使用SO_BINDTODEVICE选项的替代方法。

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

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

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

+0

感谢您的回复 – 2012-08-27 23:30:50

相关问题