为什么UDP套接字的socket.makefile对象在第一次读取后失效?

2 投票
1 回答
1313 浏览
提问于 2025-04-15 21:44

我正在使用 socket.makefile 方法,在一个UDP套接字上创建一个类似文件的对象,目的是为了读取数据。当我收到一个UDP数据包时,我可以通过使用read方法一次性读取整个数据包的内容,但如果我尝试分开多次读取,程序就会卡住。

下面是一个演示这个问题的程序:

import socket
from sys import argv

SERVER_ADDR = ("localhost", 12345)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(SERVER_ADDR)
f = sock.makefile("rb")

sock.sendto("HelloWorld", SERVER_ADDR)

if "--all" in argv:
    print f.read(10)
else:
    print f.read(5)
    print f.read(5)

如果我用 --all 选项运行上面的程序,它就能正常工作,并打印出 HelloWorld。但是如果我不加这个选项,它会先打印 Hello,然后在第二次读取时就卡住了。我在使用TCP套接字时,使用 socket.makefile 对象没有这个问题。

这到底是为什么呢?我该怎么做才能解决这个问题?

1 个回答

2

你发送了一个数据包,但调用了两次读取操作。第二次读取不会有任何数据,因为没有新的数据包可以读取。UDP套接字的读取操作一次只能读取一个数据包,如果你没有读取完所有的字节,剩下的数据就会被丢弃。UDP不是以流的方式工作的,而是以消息或数据报的方式。

UDP和文件的概念不太一样。一个“文件”只是字节的流,而不是数据包的集合,而且它是有结尾的。就像TCP一样,你从中读取字节——你使用多少次读取来获取数据并不重要,而且你可以检测到它的结束。

撰写回答