Building a Simple File Sharing System with Python Sockets and Tkinter

In today’s interconnected world, the ability to share files seamlessly between devices is essential. Whether for collaborative projects or transferring documents, having a reliable means of file exchange can greatly enhance productivity. In this tutorial, we’ll guide you through creating a basic file sharing system using Python’s socket programming and Tkinter for the graphical user interface (GUI).

Introduction

Python’s socket module provides a robust framework for network communication, enabling the creation of both client and server applications. When combined with Tkinter’s GUI capabilities, we can develop an intuitive interface for both sending and receiving files over a local network.

Setting Up the Environment

Before we begin, ensure Python is installed on your system. Tkinter comes pre-installed with most Python distributions, so no additional setup is required.

Server-side Implementation

Let’s start by examining the code for the server component of our file sharing system:

import socket
import threading
import os
import tkinter as tk
from tkinter import filedialog, messagebox

# Define server IP address and port
SERVER_HOST = '127.0.0.1'
SERVER_PORT = 12345
BUFFER_SIZE = 4096

class ServerGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("File Server")

        self.file_label = tk.Label(root, text="No file selected", font=("Helvetica", 12))
        self.file_label.pack(pady=10)

        self.select_button = tk.Button(root, text="Select File", command=self.select_file, font=("Helvetica", 12))
        self.select_button.pack(pady=5)

    def select_file(self):
        file_path = filedialog.askopenfilename()
        if file_path:
            self.file_label.config(text=file_path)
            threading.Thread(target=self.start_server, args=(file_path,)).start()

    def start_server(self, file_path):
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.bind((SERVER_HOST, SERVER_PORT))
        server_socket.listen(1)
        print(f"[*] Server listening on {SERVER_HOST}:{SERVER_PORT}")

        while True:
            client_socket, client_address = server_socket.accept()
            print(f"[*] Accepted connection from {client_address[0]}:{client_address[1]}")
            threading.Thread(target=self.handle_client, args=(client_socket, file_path)).start()

    def handle_client(self, client_socket, file_path):
        try:
            with open(file_path, 'rb') as file:
                file_data = file.read()
                client_socket.sendall(file_data)
                print("[*] File sent successfully.")
                messagebox.showinfo("Success", "File sent successfully.")
        except FileNotFoundError:
            print("[!] File not found.")
            client_socket.sendall(b'File not found')
        finally:
            client_socket.close()

def main():
    root = tk.Tk()
    root.geometry("300x200")
    root.configure(bg="#f0f0f0")
    server_gui = ServerGUI(root)
    root.mainloop()

if __name__ == "__main__":
    main()

Client-side Implementation

Now let’s examine the code for the client component of our file sharing system:

import socket
from tkinter import Tk, Button, Label, filedialog, messagebox

# Define server IP address and port
SERVER_HOST = '127.0.0.1'
SERVER_PORT = 12345
BUFFER_SIZE = 4096

class ClientGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("File Receiver")
        self.root.geometry("300x150")

        self.file_label = Label(root, text="No file received", font=("Helvetica", 12))
        self.file_label.pack(pady=10)

        self.receive_button = Button(root, text="Receive File", command=self.receive_file, font=("Helvetica", 12))
        self.receive_button.pack(pady=5)

    def receive_file(self):
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            client_socket.connect((SERVER_HOST, SERVER_PORT))

            file_name = filedialog.asksaveasfilename(defaultextension=".*")
            if file_name:
                with open(file_name, 'wb') as file:
                    while True:
                        file_data = client_socket.recv(BUFFER_SIZE)
                        if not file_data:
                            break
                        file.write(file_data)
                self.file_label.config(text=f"File saved as: {file_name}")
                print("[*] File received and saved.")
                messagebox.showinfo("Success", "File received and saved successfully.")
            else:
                print("[!] No file name provided.")
        except Exception as e:
            print(f"[!] Error: {e}")
            messagebox.showerror("Error", f"An error occurred: {e}")
        finally:
            client_socket.close()

def main():
    root = Tk()
    client_gui = ClientGUI(root)
    root.mainloop()

if __name__ == "__main__":
    main()

Conclusion

Congratulations! You’ve successfully created a basic file sharing system with Python sockets and Tkinter. This system allows users to share files over a local network, providing a simple yet effective means of collaboration and file exchange.

Feel free to customize and expand upon this system to suit your specific requirements. You might consider adding features such as authentication, encryption, or support for transferring multiple files simultaneously.

Exploring network programming with Python opens up a world of possibilities for building powerful and scalable applications. Happy coding!

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Basket