views:

34

answers:

1

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 works 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?

+1  A: 

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.

nos