2013-07-31 4 views
1

Im кодирует скрипт python, который подключается к удаленному серверу, и анализирует возвращаемый ответ. По какой-то нечетной причине, 9 из 10 раз. После того, как заголовок прочитан, сценарий продолжается и возвращается, прежде чем получить тело ответа. Я не эксперт на python, но я уверен, что мой код верен на стороне python. Вот мой код:Частичное чтение из 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() для чтения тела. Как указано выше, 9 из 10 раз, чтение ничего не возвращает или просто частичные данные.

Пример использования:

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.Close() после http.read(), я все равно получаю частичные чтения – Wilson212

+0

Я не могу воспроизвести поведение, которое вы видите, используя www .google.com /, stackoverflow.net/ или linux.die.net/. Можете ли вы протестировать против общедоступного веб-сервера и указать мне имя веб-сервера, с которым он не работает? –

+0

Я на самом деле просто нашел ошибку, но я до сих пор не знаю, как ее исправить. Исключение (10054, «Сброс соединения сверстником»). Im тестирование против моего локального HttpListener (.Net 4.0) – Wilson212

Смежные вопросы