[Python-es] Transferencia archivos grandes en socket

Alexis Roda alexis.roda.villalonga en gmail.com
Lun Abr 22 13:31:56 EDT 2019


Hola,
tal vez el problema es que guardas en memoria el archivo, en una cadena.
Las cadenas son inmutables, eso significa que la linea "buf +=
socket_cliente(...)" hace algo parecido a:

- reserva un nuevo bloque de memoria
- copia el valor original de buf
- copia el valor devuelto por la función

eso en cada iteración. No escala bien. Si además el archivo es grande, en
comparación con la RAM del equipo, puede ocasionar el uso de la memoria de
intercambio y ralentizar las cosas aún mas.

Prueba grabando en disco cada bloque según le recibes en lugar de esperar a
tenerlos todos y guardar al final.


Missatge de PeRy <perysoy en gmail.com> del dia dl., 22 d’abr. 2019 a les 2:50:

>
> 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
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20190422/a0db1ef0/attachment.html>


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