我在获取 python 文档中显示的用于记录 DatagramHandler 的示例代码时遇到问题,下面显示的代码在收到的每个数据报上都会给出 EOFError 异常。
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()
无论这段代码如何工作,有什么想法
data, address = sock.recvfrom(8192)
rec = logging.makeLogRecord(cPickle.loads(data[4:]))
logger.handle(rec)
问候
最佳答案
我希望您的第一个 recv(4)
调用会复制数据报中的前四个字节,然后将数据包的其余部分扔到地板上;第二次调用 recv
然后发现没有任何内容可读取并返回 EOFError。从我的系统的 udp(7)
联机帮助页:
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.
尝试读入整个数据报,获取前四个字节的长度,然后处理存储整个数据报的数组子集。
当然,如果你的泡菜不完全符合 MTU的连接,它可能永远不会按您的预期工作。
关于Python 日志记录数据报处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4397620/