Enviar archivo vía socket



Versión: 2.x, 3.x.
Descarga: sendfile.zip.

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()



9 comentarios.

  1. 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?

  2. 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

  3. 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 un comentario