Enviar archivo vía socket

Versión: 2.x, 3.x.
Descarga: sendfile.zip.
Nota: Hay una versión más eficiente y actualizada a Python 3.8 de este mismo código aquí: Enviar archivo vía socket en Python 3. A menos que se necesite compatibilidad con Python 2, recomendamos esta nueva implementación.

Simple conexión que permite enviar cualquier archivo desde el cliente hacia el servidor.

Desde el cliente se lee un determinado fichero de a porciones de 1024 bytes, que son enviadas al servidor hasta que todo el contenido se haya retornado.

Cliente

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#      client.py
#
#      Copyright 2014 Recursos Python - www.recursospython.com
#
#

from socket import socket


def main():
    s = socket()
    s.connect(("localhost", 6030))
    
    while True:
        f = open("archivo.jpg", "rb")
        content = f.read(1024)
        
        while content:
            # Enviar contenido.
            s.send(content)
            content = f.read(1024)
        
        break
    
    # Se utiliza el caracter de código 1 para indicar
    # al cliente que ya se ha enviado todo el contenido.
    try:
        s.send(chr(1))
    except TypeError:
        # Compatibilidad con Python 3.
        s.send(bytes(chr(1), "utf-8"))
    
    # Cerrar conexión y archivo.
    s.close()
    f.close()
    print("El archivo ha sido enviado correctamente.")


if __name__ == "__main__":
    main()

Servidor

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#      server.py
#
#      Copyright 2014 Recursos Python - www.recursospython.com
#
#

from socket import socket, error

def main():
    s = socket()
    
    # Escuchar peticiones en el puerto 6030.
    s.bind(("localhost", 6030))
    s.listen(0)
    
    conn, addr = s.accept()
    f = open("recibido.jpg", "wb")
    
    while True:
        try:
            # Recibir datos del cliente.
            input_data = conn.recv(1024)
        except error:
            print("Error de lectura.")
            break
        else:
            if input_data:
                # Compatibilidad con Python 3.
                if isinstance(input_data, bytes):
                    end = input_data[0] == 1
                else:
                    end = input_data == chr(1)
                if not end:
                    # Almacenar datos.
                    f.write(input_data)
                else:
                    break
    
    print("El archivo se ha recibido correctamente.")
    f.close()


if __name__ == "__main__":
    main()

Curso online 👨‍💻

¡Ya lanzamos el curso oficial de Recursos Python en Udemy! Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter en 2024.

Consultoría 💡

Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.

19 comentarios.

    • Recursos Python says:

      No conozco. Se podría programar, pero capaz lo mejor sea comprimir la carpeta en un ZIP, enviarlo como cualquier archivo, y luego descomprimirlo en el otro extremo.

      Saludos

  1. Estas líneas de código están mal escritas, ya que la señal que manda el cliente «chr(1)», al servidor le es imposible identificarlo.
    Por lo tanto el archivo termina cuando el cliente deja de mandar datos y no, cuando el cliente manda la señal «chr(1)» indicando el final.
    Resumen: Hay un fallo en el código y en el planteamiento, ubicado en la señal que marca el final del archivo.

    • Recursos Python says:

      Hola Abraham. El código tiene sus años, seguramente se pueda ensayar una mejor implementación, pero no veo que haya un fallo. ¿Por qué al servidor le sería imposible identificar el chr(1)?

  2. el código funciona de perlas envía archivos de cualquier tamaño y por si fuera poco también llega con el nombre original del archivo saludos.!

  3. Joaquín Asenjo says:

    hola estoy probando el código, intentado enviar una imagen desde un computador a otro, pero tengo un problema, ya que, me aparece que la conexión no se puede establecer. Qué problema puede estar ocurriendo?

    • Recursos Python says:

      Hola Joaquín, si tu cliente y servidor están en distintas computadores, tenés que cambiar las direcciones de IP en las funciones bind() y connect(). Te invito a que pases por el foro, nos muestres tu código y lo veamos con más detalle.

      Saludos

  4. buenas,

    Intenté enviar un archivo desde una raspberry a una pc y lo envía sin embargo no lo puedo abrir sino hasta que cierro el programa de server.

    Me podrían ayudar con eso?
    Gracias de antemano

  5. Ah y otra pregunta rapida, si quisiera enviar arhivos a otro pc que no este en la misma red con este mismo programa como se podria hacer?

  6. Hola a todos, alguno sabe porque cuando uso este ejemplo para enviar un arhivo pdf que pesa 10mb me salta este error.

    ConnectionResetError: [WinError 10054] Se ha forzado la interrupción de una conexión existente por el host remoto.

    y ademas con cualquier tipo de archivo los envia pero vacio sin contenido, no se si soy yo que estoy haciendo algo mal.

    • Recursos Python says:

      Hola Carlos, para estos inconvenientes te invito a que pases por el foro así podés mostrarnos tu código y los errores que estás obteniendo.

      Saludos

  7. Un duda amigo, los ejecute y me mando esto…
    Traceback (most recent call last):
    File «cf.py», line 38, in
    main()
    File «cf.py», line 12, in main
    s.connect((«localhost», 6030))
    File «/usr/lib/python2.7/socket.py», line 228, in meth
    return getattr(self._sock,name)(*args)
    socket.error: [Errno 110] Connection timed out

    • Recursos Python says:

      Es indistinto. Tanto cliente como servidor pueden enviar (send) y recibir (recv) datos. La decisión de hacerlo desde el cliente en este artículo en particular fue totalmente arbritraria.

      Si tenés algún problema con el código te invito a crear un tema en el foro.

      Un saludo.

Deja una respuesta