下面是在 Mininet 主机中打开 UDP 套接字并将收到的数据包写入文件的示例。h1 充当服务器,h2 充当客户端,客户端应该向 h1 发送消息(例如“Hello world”)。h1 应该接收此消息并将消息和地址存储在 foo.txt 文件中。但在执行此代码后,虽然创建了 foo.txt,但它是空的,不包含任何数据或信息。这是怎么回事?
mininetSocket测试.py:
#!/usr/bin/python from mininet.topo import Topo, SingleSwitchTopo from mininet.net import Mininet from mininet.log import lg, info from mininet.cli import CLI def main(): lg.setLogLevel('info') net = Mininet(SingleSwitchTopo(k=2)) net.start() h1 = net.get('h1') p1 = h1.popen('python myServer.py -i %s &' % h1.IP()) h2 = net.get('h2') h2.cmd('python myClient.py -i %s -m "hello world"' % h1.IP()) CLI( net ) p1.terminate() net.stop() if __name__ == '__main__': main()
myClient.py:
import socket, optparse parser = optparse.OptionParser() parser.add_option('-i', dest='ip', default='127.0.0.1') parser.add_option('-p', dest='port', type='int', default=12345) parser.add_option('-m', dest='msg') (options, args) = parser.parse_args() s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.sendto(options.msg, (options.ip, options.port) )
myServer.py:
import socket, optparse parser = optparse.OptionParser() parser.add_option('-i', dest='ip', default='') parser.add_option('-p', dest='port', type='int', default=12345) (options, args) = parser.parse_args() s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind( (options.ip, options.port) ) f = open('foo.txt','w') while True: data, addr = s.recvfrom(512) f.write("%s: %s\n" % (addr, data)) f.flush()
您的代码中看起来有一些问题,可能导致 foo.txt 文件为空。以下是几个可能导致问题的地方以及相应的修复建议:
foo.txt
默认情况下,recvfrom 是一个阻塞调用,直到接收到数据为止。在您的代码中,myServer.py 会一直等待接收数据。如果 myClient.py 没有成功发送数据,或者有任何网络延迟,myServer.py 可能不会执行 f.write() 操作。您可以通过添加一些日志信息来检查是否收到了数据。
recvfrom
myServer.py
myClient.py
f.write()
在您当前的代码中,myClient.py 在执行时通过 sendto 向 myServer.py 发送数据,但 myServer.py 需要等待数据到达。为了确保客户端在服务器准备好接收之前不会过早发送消息,您可以确保客户端发送数据后,服务器接收到并处理数据。
sendto
flush()
flush() 强制将数据从缓冲区写入文件,但由于您没有关闭文件,flush() 可能在应用程序结束时才起作用。如果在服务器端没有正常接收到数据,flush() 也不会起作用。
确保您有写入 foo.txt 文件的权限。如果权限不足,文件可能会被创建但无法写入。
确保 myServer.py 在 myClient.py 启动时正确地运行并绑定端口。
finally
import socket, optparse parser = optparse.OptionParser() parser.add_option('-i', dest='ip', default='') parser.add_option('-p', dest='port', type='int', default=12345) (options, args) = parser.parse_args() s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind((options.ip, options.port)) f = open('foo.txt', 'w') print(f"Server is listening on {options.ip}:{options.port}") while True: data, addr = s.recvfrom(512) print(f"Received data from {addr}: {data}") # Log received data f.write("%s: %s\n" % (addr, data)) f.flush() # Ensure the file is properly flushed and closed when the server is terminated f.close()
import socket, optparse import time parser = optparse.OptionParser() parser.add_option('-i', dest='ip', default='127.0.0.1') parser.add_option('-p', dest='port', type='int', default=12345) parser.add_option('-m', dest='msg') (options, args) = parser.parse_args() s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Adding a short delay to make sure the server is ready time.sleep(1) s.sendto(options.msg.encode(), (options.ip, options.port)) print(f"Sent message: {options.msg} to {options.ip}:{options.port}")
time.sleep(1)
f.close()
h1
h2
mininetSocket测试.py
希望这些修改可以帮助您解决问题。如果问题仍然存在,请检查 Mininet 环境中的网络配置。
Mininet