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
相关产品推荐
相关产品推荐

