I'm working on a client server script in python to transfer a file over a socket connection. The file transfer works successfully, however on the client.py, it doesn't seem to break out of the while True loop when there's no bytes_read from the socket so the program cannot continue to to run print(f"[INFO] File data has been received").
Here's what it looks like:
server.py
import socket
import threading
SERVER_PORT = 8081
TEXT_FORMAT = 'utf-8'
CHUNK_SIZE = 1024
FILE_NAME = "files_server/text"
server = socket.socket()
server.bind(('',SERVER_PORT))
def handle_client(client_connected, client_address, file_name):
# STEP 1 & 2 - Advising client of file size and file extension:
file_size = str(os.path.getsize(file_name)).encode()
client_connected.send(file_size)
file_extension = str(file_name.split(".")[-1]).encode()
client_connected.send(file_extension)
# STEP 3 - Sending file to the client:
with open(file_name, 'rb') as file:
while True:
# Read bytes by selected CHUNK Size
bytes_to_send = file.read(CHUNK_SIZE)
if not bytes_to_send:
# No more to send, file transmission completed
break
# Send chunk:
client_connected.sendall(bytes_to_send)
print('[FILE SENT SUCCESSFULLY]')
print(f"[CLOSING CONNECTION] Closing connection with {client_address}. Total Connections {threading.active_count() -1}")
def start():
server.listen(0)
print(f"[LISTENING] Server is listening on port {SERVER_PORT}")
# Accept new connections:
while True:
client_connected, client_address = server.accept()
print(f"[NEW CONNECTION] Connected with {client_address}. Total Connections {threading.active_count()}")
thread = threading.Thread(target=handle_client(client_connected,client_address,FILE_NAME))
thread.start()
start()
client.py
import socket
import datetime
import re
from tqdm import tqdm
SERVER_HOST = 'localhost'
SERVER_PORT = 8081
TEXT_FORMAT = 'utf-8'
CHUNK_SIZE = 1024
def bytes_to_human_readable(size_bytes):
if size_bytes == 0:
return "0B"
size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
i = int(math.floor(math.log(size_bytes, 1024)))
p = math.pow(1024, i)
s = round(size_bytes / p, 2)
return "%s %s" % (s, size_name[i])
client = ""
# Connecting to server:
try:
print(f"[STATUS] Connecting to {SERVER_HOST}:{SERVER_PORT}...")
client = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
client.connect((SERVER_HOST, SERVER_PORT))
print(f"[STATUS] Connected to {SERVER_HOST}:{SERVER_PORT} successfully")
except:
print("Failed to connect to server")
# STEP 1 - Receiving file size from server:
file_size_and_extension = client.recv(10).decode()
# file_size = bytes_to_human_readable(int(file_size))
array_file_size_and_extension = re.split('(\d+)',file_size_and_extension)
file_size = array_file_size_and_extension[1]
file_extension = array_file_size_and_extension[2]
print(f"[INFO] File size is {file_size} and extension is {file_extension}")
# STEP 3 - Downloading file:
currentDT = datetime.datetime.now()
file_name = 'files_client/' + currentDT.strftime("%Y-%m-%d %H:%M:%S")
progress = tqdm(range(int(file_size)), f"Receiving {file_name}", unit="B", unit_scale=True, unit_divisor=CHUNK_SIZE)
with open(file_name, "wb") as file:
while True:
# Read chunk size from socket
bytes_read = client.recv(CHUNK_SIZE)
if not bytes_read:
# Nothing has been received, file transmission is complete
break
file.write(bytes_read)
progress.update(len(bytes_read))
progress.close()
print(f"[INFO] File data has been received")
client.close()