python - 尽管有多个套接字,但所有接口(interface)都未被使用

标签 python sockets network-programming udp mininet

尽管将两个 UDP 套接字绑定(bind)到主机不同接口(interface)上的 2 个不同地址,但流量流经单个接口(interface)。

网络的拓扑结构如下: h2 和 s1 之间有 2 个链接 h1 和 s1 之间的 1 个链接

 ________
|        |
h2       s1_______h1
|________|

我在 mininet 上模拟 2 台主机和一台交换机。 h1 在 10.0.0.1:4243 运行一个 UDP 服务器。另一台主机有 2 个接口(interface),ips 10.0.0.2 & 10.0.0.4。我在 h2 上制作 2 个套接字,将一个绑定(bind)到 (10.0.0.2,9999),另一个绑定(bind)到 (10.0.0.4,8888)。我正在运行下面的代码,它应该在两个接口(interface)上交替发送数据包。

相反,第一个数据包在两个接口(interface)上发送。所有后续数据包都通过单个接口(interface)发送。

客户端代码(在h2上运行)

def client():
    sock1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock1.bind(("10.0.0.2",9999))

    sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock2.bind(("10.0.0.4",8888))

    while True:
        text = 'The time is {}'.format(datetime.now())
        data = text.encode('ascii')

        sock1.sendto(data, ('10.0.0.1', 4243))
        data, address = sock1.recvfrom(MAX_BYTES)

        sock2.sendto(data, ('10.0.0.1', 4243))
        data, address = sock2.recvfrom(MAX_BYTES)

服务器代码(在 h1 上运行)

def server():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('10.0.0.1', 4243))
    print('Listening at {}'.format(sock.getsockname()))
    while True:
        data, address = sock.recvfrom(MAX_BYTES)
        text = data.decode('ascii')
        print('The client at {} says {!r}'.format(address, text))
        text = 'Your data was {} bytes long'.format(len(data))
        data = text.encode('ascii')
        sock.sendto(data, address)

一个数据包通过 h2 的两个接口(interface)发送。随后的数据包都仅通过 IP 10.0.0.2 的接口(interface)发送和接收。在 wiresharking 上,一半的数据包将 src/dest IP 设置为 10.0.0.4

最佳答案

根据您的评论,这是我认为正在发生的事情:

  1. 您有冲突的默认路由
  2. 您已启用 ip_forwarding 以允许内部路由
  3. 由于#1 和#2,绑定(bind)调用基本上被否定了

冲突的默认路由

根据您的评论,这两个接口(interface)可能都有一个/8。这意味着对于 h2,内核会为两者添加相同的路由,例如:

10.0.0.0/8 dev h2-eth0 proto kernel scope link src 10.0.0.2 
10.0.0.0/8 dev h2-eth1 proto kernel scope link src 10.0.0.4 

这意味着内核只想选择其中一个来发送所有 10.0.0.0/8 流量到/从。您正在尝试通过绑定(bind)调用来解决此问题,但我认为绑定(bind)不会覆盖路由表行为。

ip_forwarding

如果设置了这个标志,它也会使事情复杂化,因为它可能允许通过 eth0 的 eth1 流量。

绑定(bind)

因此将所有这些放在一起,您将套接字绑定(bind)到与各个接口(interface)相关联的各个 IP,但内核只想将目的地为 10.0.0.1 的流量路由到一个接口(interface)并且它选择了 eth0。我认为通常这会阻止 eth1 流量,但由于路由和 ip_forward 标志,eth1 流量通过 eth0 路由(在初始 ARP 数据包之后,您看到的那个数据包)。

解决方案

给h1的接口(interface)两个IP地址10.1.0.1/16和10.0.0.1/16。然后给h2-eth0 ip地址10.0.0.2/16和h2-eth1 ip地址10.1.0.2/16。然后让您的程序从 10.1.0.2 向 10.1.0.1 发送数据,从 10.0.0.2 向 10.0.0.1 发送数据。

通过隔 ionic 网,您将防止混淆的根本原因,即路由冲突。

关于python - 尽管有多个套接字,但所有接口(interface)都未被使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57870060/

相关文章:

python - Pandas 数据框 : Count unique words in a column and return count in another column

python - 模板中的 GAE "for each"?

python - 如何在 Jupyter Notebook 的单个单元格中的多个 print() 命令的结果之间添加行距?

c - 绑定(bind)套接字时如何不破坏 UDP 端口?

python - 我们可以在Python中打印socket.getfqdn和socket.gethostbyname的输出吗

python - 存储程序序列的数据结构 - Python

java - 独立的 Java 应用程序在几天后死掉

Java套接字编程

c - IP_RECVDSTADDR 未定义

c - 如何用c检查互联网连接?