Python局域网文件下载

引言

在日常工作和生活中,我们经常需要从局域网中的其他设备上下载文件。本文将介绍如何使用Python编写一个简单的局域网文件下载工具,帮助我们方便地获取其他设备上的文件。

问题分析

在局域网中,每个设备都有一个唯一的IP地址,我们需要通过设备的IP地址来建立网络连接,并从中获取文件。为了实现这个目标,我们将使用Python的socket和urllib库。

首先,我们需要确定两个设备之间的网络连接。设备A作为下载方,需要知道设备B的IP地址和要下载的文件路径。设备B作为提供方,需要开启一个服务,等待设备A的连接,并将文件发送给设备A。

为了实现上述功能,我们可以定义两个Python类:DownloaderProviderDownloader类表示下载方,负责与Provider建立连接并接收文件。Provider类表示提供方,负责接收下载请求并发送文件。

类图

下面是DownloaderProvider类的类图:

classDiagram
    class Downloader {
        +__init__(ip: str)
        +download_file(file_path: str)
    }
    
    class Provider {
        +__init__(ip: str, file_path: str)
        +start_server()
    }
    
    class Socket {
        +__init__(ip: str, port: int)
        +connect()
        +send(data: str)
        +receive() -> str
        +close()
    }
    
    class File {
        +__init__(file_path: str)
        +read() -> bytes
    }
    
    Downloader --> Socket
    Downloader --> File
    Provider --> Socket
    Provider --> File

实现步骤

第一步:实现Socket类

首先,我们需要实现一个Socket类,用于建立网络连接、发送和接收数据。下面是Socket类的代码:

class Socket:
    def __init__(self, ip: str, port: int):
        self.ip = ip
        self.port = port
        self.socket = None

    def connect(self):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect((self.ip, self.port))

    def send(self, data: str):
        self.socket.sendall(data.encode())

    def receive(self) -> str:
        data = self.socket.recv(1024)
        return data.decode()

    def close(self):
        self.socket.close()

第二步:实现File类

接下来,我们需要实现一个File类,用于读取文件内容。下面是File类的代码:

class File:
    def __init__(self, file_path: str):
        self.file_path = file_path

    def read(self) -> bytes:
        with open(self.file_path, 'rb') as file:
            data = file.read()
        return data

第三步:实现Downloader类和Provider类

现在我们可以实现DownloaderProvider类了。Downloader类负责与Provider建立连接并接收文件,Provider类负责接收下载请求并发送文件。下面是DownloaderProvider类的代码:

class Downloader:
    def __init__(self, ip: str):
        self.ip = ip

    def download_file(self, file_path: str):
        # 建立连接
        socket = Socket(self.ip, 5000)
        socket.connect()

        # 发送下载请求
        socket.send(file_path)

        # 接收文件内容
        data = socket.receive()

        # 保存文件
        with open(file_path, 'wb') as file:
            file.write(data)

        # 关闭连接
        socket.close()


class Provider:
    def __init__(self, ip: str, file_path: str):
        self.ip = ip
        self.file_path = file_path

    def start_server(self):
        # 创建服务端Socket
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.bind((self.ip, 5000))
        server_socket.listen(1)

        print(f"Waiting for connection on {self.ip}:5000...")

        while True:
            # 等待连接
            client_socket, address = server_socket.accept()
            print(f"Connected to {address[0]}:{address[1]}")

            # 接收下载请求
            file_path = client_socket.recv(1024).decode()
            print(f"Download request: {file_path}")

            # 读取文件内容