2013-07-31 2 views
1

Im은 원격 서버에 연결하는 python 스크립트를 코딩하고 반환 된 응답을 구문 분석합니다. 이상한 이유로 10 번 중 9 번, 헤더가 읽히면 스크립트가 계속 응답의 본문을 가져 오기 전에 반환됩니다. 나는 파이썬에서 전문가가 아니지만, 내 코드가 사물의 파이썬 측면에서 정확하다는 것을 확신한다.부분 읽기 from Socket.File.Read

class miniclient: 
"Client support class for simple Internet protocols." 

def __init__(self, host, port): 
    "Connect to an Internet server." 


    self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    self.sock.settimeout(30) 

    try: 
     self.sock.connect((host, port)) 
     self.file = self.sock.makefile("rb") 

    except socket.error, e: 

     #if e[0] == 111: 
     # print "Connection refused by server %s on port %d" % (host,port) 
     raise 


def writeline(self, line): 
    "Send a line to the server." 

    try: 
     # Updated to sendall to resolve partial data transfer errors 
     self.sock.sendall(line + CRLF) # unbuffered write 

    except socket.error, e: 
     if e[0] == 32 : #broken pipe 
      self.sock.close() # mutual close 
      self.sock = None 

     raise e 

    except socket.timeout: 
     self.sock.close() # mutual close 
     self.sock = None 
     raise 

def readline(self): 
    "Read a line from the server. Strip trailing CR and/or LF." 

    s = self.file.readline() 

    if not s: 
     raise EOFError 

    if s[-2:] == CRLF: 
     s = s[:-2] 

    elif s[-1:] in CRLF: 
     s = s[:-1] 

    return s 


def read(self, maxbytes = None): 
    "Read data from server." 

    if maxbytes is None: 
     return self.file.read() 

    else: 
     return self.file.read(maxbytes) 


def shutdown(self): 

    if self.sock: 
     self.sock.shutdown(1) 


def close(self): 

    if self.sock: 
     self.sock.close() 
     self.sock = None 

내가 (헤더와 바디 사이의 구분) 빈 라인에 도달 할 때까지 헤더를 읽어에서는 ReadLine() 메소드를 사용 : 여기 내 코드입니다. 거기에서 내 객체는 "Read()"메서드를 호출하여 본문을 읽습니다. 앞에서 설명한 것처럼 10 번 중 9 번, read는 아무 것도 반환하지 않거나 일부 데이터 만 반환합니다.

사용 예 :

try: 
    http = miniclient(host, port) 

except Exception, e: 

    if e[0] == 111: 
     print "Connection refused by server %s on port %d" % (host,port) 

    raise 

http.writeline("GET %s HTTP/1.1" % str(document)) 
http.writeline("Host: %s" % host) 
http.writeline("Connection: close") # do not keep-alive 
http.writeline("") 
http.shutdown() # be nice, tell the http server we're done sending the request 

# Determine Status 
statusCode = 0 
status = string.split(http.readline()) 
if status[0] != "HTTP/1.1": 
    print "MiniClient: Unknown status response (%s)" % str(status[0]) 

try: 
    statusCode = string.atoi(status[1]) 
except ValueError: 
    print "MiniClient: Non-numeric status code (%s)" % str(status[1]) 

#Extract Headers 
headers = [] 
while 1: 
    line = http.readline() 
    if not line: 
     break 
    headers.append(line) 

http.close() # all done 

#Check we got a valid HTTP response 
if statusCode == 200: 
    return http.read() 
else: 
    return "E\nH\terr\nD\tHTTP Error %s \"%s\"\n$\tERR\t$" % (str(statusCode), str(status[2])) 
+0

, 정확하게, 당신의 질문은 무엇입니까? –

+0

제 질문은 때때로 내가 전체 읽기를 얻는 이유입니다. – Wilson212

답변

2

잘못된 대답은 제거되었지만 아직 삭제되지 않습니다 (그래서 코멘트 잠시 동안 살 수 있습니다.)

+0

http.read() 후에 http.Close()를 이동 한 후에도 여전히 부분 읽기가 발생합니다. – Wilson212

+0

www를 사용하여 볼 수있는 동작을 재현 할 수 없습니다. .google.com /, stackoverflow.net/ 또는 linux.die.net/. 공개적으로 볼 수있는 웹 서버를 테스트하고 실패한 웹 서버의 이름을 알려주시겠습니까? –

+0

나는 실제로 오류를 발견했으나 아직도 해결 방법을 모른다. 예외 (10054, '동료에 의한 연결 재설정'). 내 로컬 HttpListener (.Net 4.0)에 대한 Im 테스트 – Wilson212