Mono Socket.Bind 在连接之前使用特定接口

本文关键字:接口 Socket Bind 连接 Mono | 更新日期: 2023-09-27 18:33:43

我正在尝试使用特定的本地接口连接到远程服务器。我的日志告诉我一切都按预期工作,但检查 netstat,每个连接都使用默认接口。

我使用以下代码将 TcpClient 绑定到特定的本地终结点

Console.WriteLine("Binding to {0}", connectionArgs.LocalBindingInterface.ToString());
client = new TcpClient(connectionArgs.LocalBindingInterface);
Console.WriteLine("Bound to {0}", client.Client.LocalEndPoint.ToString());

其中 connectionArgs.LocalBindingInterface 是指定的 IPEndPoint

IPEndPoint[] localEndPoints = new IPEndPoint[2];
localEndPoints[0] = new IPEndPoint(IPAddress.Parse("192.168.0.99"), 0);
localEndPoints[1] = new IPEndPoint(IPAddress.Parse("192.168.0.100"), 0);

此处列出的 IP 地址不是实际地址。

当我检查我的日志时,这是我得到的信息

Binding to 192.168.0.99:0
Bound to 192.168.0.99:59252
Binding to 192.168.0.100:0
Bound to 192.168.0.100:53527

但是当我netstat -n -p --tcp -a时,我得到了

tcp        0      0 192.168.0.98:39948    remote_addr_here:443       ESTABLISHED 17857/mono
tcp        0      0 192.168.0.98:60009    remote_addr_here:443       ESTABLISHED 17857/mono

显然这里有些不对劲。所有端口和接口都不匹配。Netstat 作为 sudo 运行,所以我不能假设它是错误的。我还尝试手动创建一个套接字,调用它的绑定方法,并将 TcpClient 的 Client 属性设置为手动绑定的套接字,但我得到了相同的结果。

我在这里做错了什么吗?有没有其他方法可以强制套接字在单声道上使用特定的本地端点?

我以非 root 用户身份运行此应用程序,mono --version 是 Mono JIT compiler version 3.2.8 (Debian 3.2.8+dfsg-4ubuntu1.1),服务器的 ubuntu 版本是 Ubuntu 14.04.3 LTS

编辑 1:

在调用 TcpClient.Connect(( 后添加了额外的日志记录调用

Binding to 192.168.0.100:59000
Bound to 192.168.0.100:59000
After connect bound to 192.168.0.98:55484

Mono Socket.Bind 在连接之前使用特定接口

底线:你不能这样做,不能在套接字级别。

出站流量的路由由网络路由配置确定。您必须为目标创建显式路由表条目,以强制使用特定的适配器。

您可以绑定到特定的 IP 地址,但这只会导致入站流量被过滤,即您只会收到发送到该 IP 地址的流量。


您可能还想阅读一些相关问题:

如何停止行为:C++套接字发送更改界面 — 上下文是C++的,不限于 Windows,但它具有恕我直言,关于该主题的最直接、最相关的注释。

在Windows中为套接字使用特定的网络接口 - 坦率地说,问题和答案都相当糟糕。但它确实包含一些引号和链接,无论如何您都可能会发现它们很有用。

可以说,这个问题可能已经作为其中一个问题的重复,甚至可能是另一个类似的问题而结束。但是这两个并不能真正准确地回答这个问题,C#/。NET特有的方式,我实际上没有找到任何其他看起来更好的方式。