关于c#:Mono Socket.Bind连接之前要使用特定的接口

 2021-04-27 

Mono Socket.Bind before connecting to use a specific interface

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

我正在使用以下代码将TcpClient绑定到特定的本地端点

1
2
3
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

1
2
3
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地址不是实际地址。

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

1
2
3
4
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时我得到

1
2
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运行,所以我不能认为这是错误的。我还尝试手动创建一个套接字,将其称为bind方法,并将TcpClient的Client属性设置为手动绑定的套接字,但是得到的结果相同。

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

我以非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()

之后添加了一个额外的日志记录调用

1
2
3
Binding to 192.168.0.100:59000
Bound to 192.168.0.100:59000
After connect bound to 192.168.0.98:55484

底线:您不能执行此操作,而不是在套接字级别。

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

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

您可能还需要阅读一些相关的问题:

如何停止行为:C套接字sendto更改接口-上下文是C且不限于Windows,但是它具有IMHO关于该主题最直接,最相关的注释。

在Windows中为套接字使用特定的网络接口-坦率地说,这是一个很差的问题,要回答这两个问题。但是它确实包含一些引号和链接,您可能仍然会发现它们有用。

可以说,这个问题可能已经作为其中一个甚至另一个类似问题的副本被关闭了。但是,这两个人并没有以准确的,特定于C#/。NET的方式真正地回答了这个问题,而且我实际上没有发现其他任何看起来更好的人。