You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mininet环境下Host2无法接收Host1发送的UDP数据包问题排查

Mininet UDP通信故障排查:发送10个包但无接收

问题描述

我尝试在Mininet的host1与host2之间建立UDP连接,host1已成功发送10个数据包,但host2未收到任何来自host1的数据包,请问代码中是否存在配置错误?

原代码

from mininet.net import Mininet
from mininet.link import TCLink
import random
import re

def simulate_packet_loss():
    # Create Mininet network
    net = Mininet()

    # Add hosts and switches
    host1 = net.addHost('h1', ip='10.0.0.1/24')
    host2 = net.addHost('h2', ip='10.0.0.2/24')
    switch = net.addSwitch('s1')

    # Add links between hosts and switch with manipulated bandwidth
    bandwidth = random.randint(1, 10)  # Manipulated bandwidth in Mbps
    loss_percentage = random.randint(1, 10)  # Desired packet loss percentage
    link1 = net.addLink(host1, switch, cls=TCLink, bw=bandwidth, loss=loss_percentage)
    link2 = net.addLink(host2, switch, cls=TCLink, bw=bandwidth, loss=loss_percentage)

    # Start the network
    net.start()

    # Start UDP server on host2 to receive packets
    udp_server_script = """
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('10.0.0.2', 5000))
packets_received = 0
output_file = open('/tmp/output.txt', 'w')
while True:
    data, addr = s.recvfrom(1024)
    packets_received += 1
    print('Received packet:', data)
    output_file.write('Received packet: ' + data.decode('utf-8') + '\\n')
    output_file.flush()
output_file.close()
"""
    with open('/tmp/udp_server.py', 'w') as f:
        f.write(udp_server_script)
    host2.cmd('python /tmp/udp_server.py &')

    # Send UDP packets from host1 to host2
    packets_sent = 0  # Counter for packets sent
    while packets_sent < 10:
        host1.cmd('echo "UDP Packet" | nc -u -w1 10.0.0.2 5000')  # Send UDP packets to host2 IP address
        packets_sent += 1  # Increment the counter for each packet sent

    # Retrieve the number of packets received from the output file
    output = host2.cmd('timeout 1 cat /tmp/output.txt')
    if output is None:
        output = ''
    else:
        output = output

    # Stop the UDP server on host2
    host2.cmd('kill %python')

    # Stop the network
    net.stop()

    # Print the number of packets sent and received
    print('Number of Packets Sent:', packets_sent)

    packets_received = len(re.findall(r'Received packet:.*', output))
    print('Number of Packets Received:', packets_received)

if _name_ == '_main_':
    simulate_packet_loss()

错误点分析及修复

1. 脚本入口语法错误

原代码最后一行的if _name_ == '_main_':使用了单下划线,正确写法是双下划线:

if __name__ == '__main__':

单下划线会导致核心函数simulate_packet_loss()根本不会执行,这是最关键的问题。

2. UDP服务器启动后无延迟

启动服务器后立刻发送数据包,此时服务器可能还未完成端口绑定,导致数据包无法被接收。需要添加初始化延迟:

import time
# ... 启动服务器代码 ...
host2.cmd('python /tmp/udp_server.py &')
time.sleep(1)  # 等待服务器完成绑定

3. nc命令超时参数不合理

nc -u -w1中的-w1设置了1秒超时,但UDP是无连接协议,该参数可能导致nc过早退出,影响数据包发送。建议去掉该参数:

host1.cmd('echo "UDP Packet" | nc -u 10.0.0.2 5000')

4. 进程杀死命令不准确

host2.cmd('kill %python')无法精准定位到udp_server.py进程,可能误杀其他Python进程或无法终止目标进程。改用更精确的命令:

host2.cmd('pkill -f udp_server.py')

5. 跨主机文件路径问题

在宿主系统创建的/tmp/udp_server.py,Mininet的host2可能无法访问(默认不共享宿主/tmp目录)。应直接在host2内部创建脚本:

# 替换原有的文件写入和启动逻辑
host2.cmd('cat > /tmp/udp_server.py << "EOF"')
host2.cmd(udp_server_script)
host2.cmd('EOF')
host2.cmd('python /tmp/udp_server.py &')

修复后的完整代码

from mininet.net import Mininet
from mininet.link import TCLink
import random
import re
import time

def simulate_packet_loss():
    # Create Mininet network
    net = Mininet()

    # Add hosts and switches
    host1 = net.addHost('h1', ip='10.0.0.1/24')
    host2 = net.addHost('h2', ip='10.0.0.2/24')
    switch = net.addSwitch('s1')

    # Add links between hosts and switch with manipulated bandwidth
    bandwidth = random.randint(1, 10)  # Manipulated bandwidth in Mbps
    loss_percentage = random.randint(1, 10)  # Desired packet loss percentage
    link1 = net.addLink(host1, switch, cls=TCLink, bw=bandwidth, loss=loss_percentage)
    link2 = net.addLink(host2, switch, cls=TCLink, bw=bandwidth, loss=loss_percentage)

    # Start the network
    net.start()

    # Start UDP server on host2 to receive packets
    udp_server_script = """
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('0.0.0.0', 5000))  # 绑定所有网卡更可靠
packets_received = 0
output_file = open('/tmp/output.txt', 'w')
while True:
    try:
        data, addr = s.recvfrom(1024)
        packets_received += 1
        print('Received packet:', data)
        output_file.write('Received packet: ' + data.decode('utf-8') + '\\n')
        output_file.flush()
    except:
        break
output_file.close()
"""
    # 在host2内部创建脚本
    host2.cmd('cat > /tmp/udp_server.py << "EOF"')
    host2.cmd(udp_server_script)
    host2.cmd('EOF')
    host2.cmd('python /tmp/udp_server.py &')

    # 等待服务器启动
    time.sleep(1)

    # Send UDP packets from host1 to host2
    packets_sent = 0  # Counter for packets sent
    while packets_sent < 10:
        host1.cmd('echo "UDP Packet {}" | nc -u 10.0.0.2 5000'.format(packets_sent+1))
        packets_sent += 1
        time.sleep(0.1)  # 避免发送过快导致丢包

    # Retrieve the number of packets received from the output file
    output = host2.cmd('cat /tmp/output.txt')
    output = output or ''

    # Stop the UDP server on host2
    host2.cmd('pkill -f udp_server.py')

    # Stop the network
    net.stop()

    # Print the number of packets sent and received
    print('Number of Packets Sent:', packets_sent)

    packets_received = len(re.findall(r'Received packet:.*', output))
    print('Number of Packets Received:', packets_received)

if __name__ == '__main__':
    simulate_packet_loss()

内容的提问来源于stack exchange,提问作者unknown-kid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 15:34:52