[Python-es] Transferencia archivos grandes en socket

PeRy perysoy en gmail.com
Lun Abr 22 15:13:23 EDT 2019


Hola de nuevo Javi,

Vale ya lo tengo... no era solo escribir lo recibido en cada pasada sino
quitar los buff+=


muchas gracias a todos por vuestro tiempo!

El lun., 22 abr. 2019 a las 20:43, lasizoillo (<lasizoillo en gmail.com>)
escribió:

> Tiene toda la pinta de ser lo que te dice Alexis Roda. Piensa que cada vez
> que haces crecer buf (buf+=recv(...)) pasa lo siguiente:
> - buf apunta a obj1 en memoria
> - lees el dato del socket creando obj2, también en memoria
> - reserva el espacio para obj3 en memoria cuyo tamaño será aprox la suma
> de los tamaños obj1 y obj2
> - copias el contenido de obj1 y obj2 sobre obj3
> - buf apunta a obj3
> - obj1 y obj2 pierden referencias por lo que son destruidos y vaciados de
> memoria
>
> Como te puedes imaginar cuanto más grande es buf más trabajo le toca
> hacer. La memoria se fragmenta, así que aunque creas que solo usas el
> resultado de la copia (y copias muchas veces) usas más memoria. Cuando
> llenas la memoria toca swapear (y eso es varios órdenes de magnitud más
> lento).
>
> Haz caso a Alexis y escribe directo a disco sin mega buffers en memoria.
> La parte de leer bloques ya lo estás haciendo bien.
>
> Te paso una entrada a un blog donde de propina habla de como usar sendfile
> para evitar copias entre kerner y memoria de usuario:
> http://michaldul.com/python/sendfile/
>
> Un saludo,
>
> Javi
>
> El lun., 22 abr. 2019 a las 19:45, PeRy (<perysoy en gmail.com>) escribió:
>
>> Hola!
>> el archivo es de 400MB, la transferencia empieza a todo lo que da la PI
>> (10-11Mb/s estoy en LAN) para después bajar a 2Mb/s y a partir de los
>> 200Megas descargados aproximadamente va bajando progresivamente terminando
>> en menos de 0.5Mb/s, Con otro archivo de mayor tamaño (1.6Gb) es igual, a
>> partir de 200 megas o así va bajando hasta 0.5Mb/s y con esa velocidad
>> hasta el final.
>>
>> un saludo
>>
>> El lun., 22 abr. 2019 a las 19:17, AGTUGO (<agtugo en gmail.com>) escribió:
>>
>>> Que tan grande el archivo? Cuanto es mucho tiempo?
>>>
>>> On Sun, Apr 21, 2019 at 5:50 PM PeRy <perysoy en gmail.com> wrote:
>>>
>>>>
>>>> Buenas! Estoy aprendiendo Python y estoy con el tema de los sockets, he
>>>> creado un servidor y cliente para enviar archivos. Me he dado cuenta que en
>>>> archivos grandes cuanto mas pasa el tiempo mas lenta se hace la recepción
>>>> de la información, ¿alguna sugerencia por qué pasa y como se podría evitar?
>>>> mi codigo:
>>>>
>>>> server:
>>>>
>>>> =============================================================================================
>>>> elif b'\F' in data: # peticion de archivo para ser descargado
>>>> transmitido = data.rstrip(b'\F')
>>>> comparte_dir = os.path.join(os.getcwd(), 'compartir')
>>>> print(os.path.join(comparte_dir, transmitido.decode()))
>>>> filesize = os.path.getsize(os.path.join(comparte_dir,
>>>> transmitido.decode()))
>>>> print("TAMAÑO: {}".format(filesize))
>>>> with open(os.path.join(comparte_dir, transmitido.decode()), 'rb') as f:
>>>> self.socket.send(struct.pack('!I', filesize))  # enviamos en los
>>>> primeros 4bytes el tamaño del archivo
>>>> numero_bytes = self.socket.sendfile(f)
>>>>                                         # data = f.read(8192)
>>>> # numero_bytes = len(data)
>>>> # self.socket.send(data)
>>>> # while data:
>>>> # data = f.read(8192)
>>>> # self.socket.send(data)
>>>> # numero_bytes += len(data)
>>>>                                 print(numero_bytes)
>>>>
>>>> cliente:
>>>>
>>>> ===============================================================================================
>>>> with open(archivo, 'wb') as f:
>>>>                         buf = socket_cliente.recv(4)  # cabecera con
>>>> elt amaño del archivo
>>>>                         filesize = struct.unpack('!I', buf)
>>>>                         print("filesize : {}".format(filesize))
>>>>                         filesize=filesize[0]
>>>>                         buf = b''
>>>>                         tiempo_inicio = datetime.datetime.now()
>>>>                         print(tiempo_inicio.strftime('%H:%M:%S'))
>>>>                         while len(buf) < filesize:
>>>>                             to_read = filesize - len(buf)
>>>>                             buf += socket_cliente.recv(262144 if
>>>> to_read > 262144 else to_read)  #8192 1024*8 o 4096 1024*4
>>>>                             updt(filesize, len(buf))  # barra de
>>>> progreso
>>>>                         f.write(buf)
>>>>
>>>> ---------------------
>>>> Muchas Gracias y un saludo
>>>>
>>>> _______________________________________________
>>>> Python-es mailing list
>>>> Python-es en python.org
>>>> https://mail.python.org/mailman/listinfo/python-es
>>>>
>>>
>>>
>>> --
>>> Arturo Muñoz Tolosa
>>> _______________________________________________
>>> Python-es mailing list
>>> Python-es en python.org
>>> https://mail.python.org/mailman/listinfo/python-es
>>>
>>
>>
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> https://mail.python.org/mailman/listinfo/python-es
>>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> https://mail.python.org/mailman/listinfo/python-es
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20190422/49cd5ef7/attachment.html>


Más información sobre la lista de distribución Python-es