小能豆

将接收到的数据写入文本文件

py

下面是在 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()

阅读 21

收藏
2024-12-05

共1个答案

小能豆

您的代码中看起来有一些问题,可能导致 foo.txt 文件为空。以下是几个可能导致问题的地方以及相应的修复建议:

1. UDP 套接字的非阻塞问题

默认情况下,recvfrom 是一个阻塞调用,直到接收到数据为止。在您的代码中,myServer.py 会一直等待接收数据。如果 myClient.py 没有成功发送数据,或者有任何网络延迟,myServer.py 可能不会执行 f.write() 操作。您可以通过添加一些日志信息来检查是否收到了数据。

2. 客户端和服务器的同步问题

在您当前的代码中,myClient.py 在执行时通过 sendtomyServer.py 发送数据,但 myServer.py 需要等待数据到达。为了确保客户端在服务器准备好接收之前不会过早发送消息,您可以确保客户端发送数据后,服务器接收到并处理数据。

3. flush() 的问题

flush() 强制将数据从缓冲区写入文件,但由于您没有关闭文件,flush() 可能在应用程序结束时才起作用。如果在服务器端没有正常接收到数据,flush() 也不会起作用。

4. 文件写入权限

确保您有写入 foo.txt 文件的权限。如果权限不足,文件可能会被创建但无法写入。

5. 确保服务器正确启动

确保 myServer.pymyClient.py 启动时正确地运行并绑定端口。

修复建议:

  1. 添加日志信息,帮助调试。
  2. 确保服务器和客户端的网络通信正常,以及正确启动服务。
  3. 在服务器端添加 finally 块以确保文件正确写入并关闭

代码修改:

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')
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()

myClient.py

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}")

主要改动:

  1. myServer.py 中添加了打印接收到的数据:这能帮助您确认服务器是否成功接收到消息。
  2. myClient.py 中添加了 time.sleep(1):让客户端等待一秒钟,确保服务器有足够的时间启动并开始监听 UDP 端口。
  3. 文件写入改为 f.close():确保在退出时正确关闭文件,避免任何未写入的数据丢失。

其他可能的问题:

  1. 确保 h1h2 之间的网络连接正常。
  2. mininetSocket测试.py 中,确保正确启动了服务器并允许客户端与服务器通信。

希望这些修改可以帮助您解决问题。如果问题仍然存在,请检查 Mininet 环境中的网络配置。

2024-12-05