2013-10-01 1 views
1

Я пытаюсь отправить большой файл в ответ http путем записи в wfile переменной BaseHTTPRequestHandler в Python, когда я пытаюсь сделать это, я заканчиваю исключение в моем коде Python всегда.Получение ошибки: [Errno 10053] при попытке отправить файл в ответе http

error: [Errno 10053] An established connection was aborted by the software in your machine

Может ли один помочь мне решить эту проблему ?? почему я получаю ошибку? Если способ отправки большого файла в HTTP-ответе не является хорошим, предложите, где я могу обратиться.

Заранее благодарен!

import os 
import urlparse 
import BaseHTTPServer 
from SocketServer import ThreadingMixIn 
import urlparse 

class Handler(BaseHTTPServer.BaseHTTPRequestHandler): 
    def handle(self): 
     BaseHTTPServer.BaseHTTPRequestHandler.handle(self) 

    def sendError(self, errorCode, errorMessage): 
     self.send_response(errorCode, errorMessage) 
     self.send_header("Content-type", "text/plain") 
     self.send_header("Content-Length", str(len(errorMessage))) 
     self.end_headers() 
     self.wfile.write(errorMessage) 

    def do_GET(self): 
     scm, netloc, path, params, query, fragment = urlparse.urlparse(self.path, 'http') 
     if path.find(".ld") > 0: 
      filename = path.rpartition("/")[2] 
      try: 
       with open(filename, 'rb') as f: 
        self.send_response(200, "Ok") 
        self.send_header("Content-type","application/octet-stream") 
        total_size = os.path.getsize(filename) 
        self.send_header("Content-Length", total_size) 
        self.end_headers() 
        self.wfile.write(f.read()) 
      except IOError: 
       self.sendError(404, "Not Found") 

class ThreadedHTTPServer(ThreadingMixIn, BaseHTTPServer.HTTPServer): 
    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): 
     BaseHTTPServer.HTTPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate) 

def main(): 
    Handler.close_connection = 0 
    Handler.protocol_version = 'HTTP/1.1' 
    global httpd 
    httpd = ThreadedHTTPServer(("", 8900), Handler) 
    httpd.daemon_threads = True 
    httpd.serve_forever() 

if __name__ == "__main__": 
    main() 

Трассировка Ошибка:

Exception happened during processing of request from ('172.24.128.21', 19418) 
Traceback (most recent call last): 
    File "C:\Python27\lib\SocketServer.py", line 593, in process_request_thread 
    self.finish_request(request, client_address) 
    File "C:\Python27\lib\SocketServer.py", line 334, in finish_request 
    self.RequestHandlerClass(request, client_address, self) 
    File "C:\Python27\lib\SocketServer.py", line 649, in __init__ 
    self.handle() 
    File "simple.py", line 10, in handle 
    BaseHTTPServer.BaseHTTPRequestHandler.handle(self) 
    File "C:\Python27\lib\BaseHTTPServer.py", line 342, in handle 
    self.handle_one_request() 
    File "C:\Python27\lib\BaseHTTPServer.py", line 310, in handle_one_request 
    self.raw_requestline = self.rfile.readline(65537) 
    File "C:\Python27\lib\socket.py", line 476, in readline 
    data = self._sock.recv(self._rbufsize) 
error: [Errno 10054] An existing connection was forcibly closed by the remote ho 
st 
+0

Я бы хорошо, если вы на самом деле при условии, исполняемую фрагмент кода ... который не сказать, что вы должны вставить весь код, но упрощенная/сокращенная версия вашего кода, которую любой может скопировать-вставить в файл '.py' и запустить, чтобы помочь вам диагностировать вашу проблему; см. http://sscce.org –

+0

Я добавил свой исполняемый фрагмент. вы можете помочь мне решить эту проблему. Файл, который я пытаюсь передать, - это файл .LD размером 60 000 КБ. –

+0

. Вставьте часть кода, которая необходима для воспроизведения проблемы, а не весь ваш проект; см. http://sscce.org; Кроме того, вы можете просто изменить существующий фрагмент, не добавляя материал в свой пост. –

ответ

0

ОК, так что я попробовал ваш код после очистки его немного:

def do_GET(self): 
     _, _, path, _, _, _ = urlparse.urlparse(self.path, 'http') 
     if path.find(".ld") > 0: 
      filename = path.rpartition("/")[2] 
      try: 
       with open(filename, 'rb') as f: 
        self.send_response(200, "Ok") 
        self.send_header("Content-type", self.headers.getheader("Content-type", "")) 
        total_size = os.path.getsize(filename) 
        self.send_header("Content-Length", total_size) 
        self.end_headers() 
        self.wfile.write(f.read()) 
      except IOError: 
       self.sendError(404, "Not Found") 

Я положил foo.pl файл в той же папке; то при выполнении curl http://localhost/foo.pl я получаю хороший ответ с содержимым файла и никаких ошибок вообще.

Я должен также сказать, что это выглядит, как вы просто пытаетесь получить имя файла без пути части, используя path.rpartition("/")[2], но для этого вы должны просто использовать os.path.basename:

>>> os.path.basename('foo/bar/baz.pl') 
'baz.pl' 

Кроме того, path.find(".ld") > 0 должен вероятно, вместо этого будет path.endswith(".ld").

EDIT: для поддержки больших файлов (эффективно):

CHUNK_SIZE = 1024 * 100 # 100kB chunks 
while True: 
    chunk = f.read(CHUNK_SIZE) 
    if not chunk: 
     break 
    self.wfile.write(chunk) 
+0

спасибо за ваше предложение, я изменю их. где я могу добавить ошибку след моего .. в исходное сообщение? –

+0

Когда я пытаюсь загрузить небольшой файл, используя мой код, его рабочая проблема связана с большими файлами. Я получаю исключение, когда я пытаюсь загрузить файл типа .ld размером 60,000kb –

+0

@ user2153447: Я изменил ответ, чтобы объяснить, как обрабатывать большие файлы (например, 60 МБ). –

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