2010-12-09 6 views
2

로깅을위한 파이썬 문서에 표시된 예제 코드를받는 데 문제가 있습니다. 아래 표시된 코드는 수신 된 모든 데이터 그램에서 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) 

감사

답변

3

나는 첫 번째 recv(4) 전화 복사 귀하의 데이터 그램 중 처음 4 바이트를 기대하고상의 패킷의 나머지를 던졌습니다 바닥; recv에 대한 두 번째 호출은 읽는 것이 없으며 EOFError를 반환합니다. 전체 데이터 그램에서

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. 

보십시오 읽기, 처음 4 바이트에서 길이를 잡아하고 전체 데이터 그램을 저장하는 배열의 부분 집합 작업 : 내 시스템의 udp(7) 맨 페이지에서.

물론 피클이 연결의 MTU 내에 완전히 들어 가지 않으면 의도 한대로 작동하지 않을 것입니다.

+0

감사합니다 sarnold, 나는 그 소용돌이를 줄 것입니다 – mikip

+0

건배 sarnold, 많이 감사합니다 – mikip