I am having a problem getting the example code shown in the python docs for the logging DatagramHandler, the code shown below gives EOFError exceptions on every datagram received.
import socket
import logging
import cPickle
import struct
import sys
sock = socket.socket (socket.AF_INET, socket.SOCK_DGRAM)
sock.bind (('localhost', 9000))
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("UDP LogViewer %(asctime)s %(message)s"))
logger = logging.getLogger("Test")
logger.addHandler(handler)
try:
while True:
dgram_size = sock.recv(4)
if len(dgram_size) < 4:
break
slen = struct.unpack(">L", dgram_size)[0]
data = sock.recv(slen)
while len(data) < slen:
data = data + sock.recv(slen - len(data))
try:
obj = cPickle.loads(data)
record = logging.makeLogRecord(obj)
logger.handle(record)
except:
print "exception", sys.exc_info()[0]
finally:
sock.close()
However this code works, any ideas
data, address = sock.recvfrom(8192)
rec = logging.makeLogRecord(cPickle.loads(data[4:]))
logger.handle(rec)
Regards
I expect your first recv(4)
call copies the first four bytes out of your datagram and then throws the rest of the packet on the floor; your second call to recv
then finds nothing to read and returns EOFError. From my system's udp(7)
manpage:
All receive operations return only one packet. When the packet
is smaller than the passed buffer, only that much data is
returned; when it is bigger, the packet is truncated and the
MSG_TRUNC flag is set. MSG_WAITALL is not supported.
Try reading in the entire datagram, grabbing the length out of the first four bytes, and then working on the subset of the array that stores the entire datagram.
Of course, if your pickles don't fit entirely within the MTU of the connection, it'll probably never work as you intend.