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

时间:2010-04-17 22:55:59

标签: python sockets udp

我正在使用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 个答案:

答案 0 :(得分:2)

您正在发送1个数据包,但请两次调用。 2. read不会读取任何内容,因为没有新的数据包可供读取/接收。在udp套接字上读取如果没有读取所有字节,则读取一个数据包并丢弃其余数据。 UDP不是面向流的,而是面向消息/数据报。

UDP不映射到文件的概念。 “文件”只是一个字节流,而不是数据包的集合,它有一个结束。这很像TCP,你从中读取字节 - 用于读取数据的读数并不重要,你可以检测到它的结束。