小编典典

打开套接字时,Python可以选择哪个网络适配器吗?

linux

运行python应用程序的目标计算机将具有三个可用的网络接口。通常,所有三个网络都将有很大的不同,但是,这三个中的两个可能存在于相似的网络上。

在下面的示例中,我无法控制ETH 2上的目标地址(因为它是预配置的系统),因此我不得不选择要以编程方式使用的适配器。

我相当确定这将取决于操作系统如何路由连接。我希望有一种使用python来解决问题的平台独立方法,因为该应用程序可能需要在Windows
7和Linux机器上运行。

范例程式码

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.0.2', 8000)) # Which device will this connect to??

正常情况

  • ETH 0来源:192.168.0.1
  • ETH 0目的地:192.168.0.2
  • ETH 1来源:10.20.30.1
  • ETH 1目的地:10.20.30.2
  • ETH 2来源:60.50.40.1
  • ETH 2目的地:60.50.40.1

可能的故障情况

  • ETH 0来源:192.168.0.1
  • ETH 0目的地:192.168.0.2
  • ETH 1来源:10.20.30.1
  • ETH 1目的地:10.20.30.2
  • ETH 2来源:192.168.0.3
  • ETH 2目的地:192.168.0.2

附加信息
适配器ETH0、1和2都连接到不同的物理网络


阅读 366

收藏
2020-06-02

共1个答案

小编典典

在Windows上,如果知道要使用的接口的IP地址,则只需在连接前绑定该IP地址即可。在Linux上,按照JimB的建议使用套接字选项SO_BINDTODEVICE(似乎也是特权调用)。

即在Windows上

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('192.168.0.1', 0))
s.connect(('...'))

在Windows下绑定源地址,即使该IP地址的路由度量成本较高,也会选择与该设备具有相同IP地址的接口。但是,这在Linux下不起作用,因为它总是用所选设备的IP地址覆盖源地址。路由仅基于目标地址来完成。似乎唯一的例外是,如果将源地址设置为127.0.0.1,那么Linux会阻止这些数据包从该包装箱中取出。

2020-06-02