Why do socket.makefile objects fail after the first read for UDP sockets?
I'm using the socket.makefile method to create a file-like object on a UDP socket for the purposes of reading. When I receive a UDP packet, I can read the entire contents of the packet all at once by using the read method, but if I try to split it up into multiple reads, my program hangs.
Here's a program which demonstrates this problem:
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)
If I run the above program with the --all
option, then it w开发者_Python百科orks perfectly and prints HelloWorld
. If I run it without that option, it prints Hello
and then hangs on the second read. I do not have this problem with socket.makefile
objects when using TCP sockets.
Why is this happening and what can I do to stop it?
You're sending 1 packet, but call read twice. The 2. read will not read anything as there's no new packets to read/receive. read on a udp socket reads one packet and discards the rest of the data if you didn't read all of the bytes. UDP is not stream oriented, it is message/datagram oriented.
UDP does not map to the concept of a file. a "file" is just a stream of bytes, not a collection of packets, and it has an end. That's much like TCP, you read bytes from it - it does not matter how many reads you use to read the data, and you can detect the end of it.
精彩评论