linux - 为什么netstat显示错误的外部地址?

标签 linux network-programming

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

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

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

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

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

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

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

-安德烈斯

最佳答案

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

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

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

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

关于linux - 为什么netstat显示错误的外部地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11847502/

相关文章:

c# - 判断 SQL Server 是否可用的最快方法

c# - 如何在 Linux 环境中将 .NET (C#) 程序发布到 AWS BeanStalk?

c - xfrm 实现 IPsec

linux - Bash - 日期命令和空格

linux - UDP如何使用绑定(bind)端口从服务器端的不同端口接收

c - Linux C 网络通信程序在调试器中有效,但在外部无效

tcp - 客户端发送的MSS和主机接收到的MSS不一致

java - 使用java通过tcp发送结构化数据的最简单方法是什么?

php - gettext 没有翻译显示

从管道 bash 脚本运行时,Python 脚本不等待用户输入