基于Python實(shí)現(xiàn)局域網(wǎng)文件傳輸工具
背景與意義
在當(dāng)今數(shù)字化辦公環(huán)境中,局域網(wǎng)文件傳輸工具已成為提高團(tuán)隊(duì)協(xié)作效率的關(guān)鍵基礎(chǔ)設(shè)施。據(jù)統(tǒng)計(jì),約78%的中小型企業(yè)在日常工作中需要頻繁進(jìn)行內(nèi)部文件共享,其中包括:
- 部門(mén)間文檔協(xié)作(Word/Excel/PPT等)
- 開(kāi)發(fā)團(tuán)隊(duì)的代碼共享
- 設(shè)計(jì)部門(mén)的媒體文件傳輸(PSD/AI/視頻等)
- 跨設(shè)備的個(gè)人文件同步
相比依賴(lài)云服務(wù)或外部網(wǎng)絡(luò),本地化解決方案具有以下顯著優(yōu)勢(shì):
- 安全性:數(shù)據(jù)不經(jīng)過(guò)第三方服務(wù)器
- 速度:局域網(wǎng)傳輸速率可達(dá)100Mbps-1Gbps
- 可靠性:不受互聯(lián)網(wǎng)連接波動(dòng)影響
- 成本效益:無(wú)需支付云存儲(chǔ)費(fèi)用
技術(shù)實(shí)現(xiàn)方案
核心架構(gòu)
本項(xiàng)目采用Python標(biāo)準(zhǔn)庫(kù)構(gòu)建,主要包含兩大模塊:
網(wǎng)絡(luò)通信層:基于Socket編程
- TCP協(xié)議保證傳輸可靠性
- 多線程處理并發(fā)連接
- 自定義文件傳輸協(xié)議頭
用戶(hù)界面層:使用Tkinter實(shí)現(xiàn)
- 簡(jiǎn)潔直觀的GUI設(shè)計(jì)
- 文件選擇對(duì)話(huà)框
- 傳輸進(jìn)度可視化
開(kāi)發(fā)環(huán)境要求
- Python 3.6+
- 標(biāo)準(zhǔn)庫(kù):
socket,threading,os,tkinter - 可選優(yōu)化庫(kù):
pyinstaller(用于打包成可執(zhí)行文件)
工具概述
本工具允許用戶(hù)在局域網(wǎng)內(nèi)發(fā)送和接收文件,無(wú)需互聯(lián)網(wǎng)連接。核心組件包括:
- Socket通信:使用Python的
socket模塊建立TCP連接,確保可靠數(shù)據(jù)傳輸。 - GUI界面:基于Tkinter,提供文件選擇、IP輸入和傳輸狀態(tài)顯示。
- 文件處理:支持任意文件類(lèi)型,自動(dòng)處理字節(jié)流分割與重組。
工具工作流程:
- 接收端啟動(dòng)服務(wù)器監(jiān)聽(tīng)。
- 發(fā)送端通過(guò)GUI選擇文件并輸入接收端IP。
- 文件數(shù)據(jù)通過(guò)Socket傳輸,實(shí)時(shí)顯示進(jìn)度。
- 接收端保存文件到本地。
實(shí)現(xiàn)步驟
我們將分步構(gòu)建工具,確保每個(gè)模塊可獨(dú)立測(cè)試。完整代碼附在最后。
步驟1:Socket服務(wù)器端(接收文件)
服務(wù)器端監(jiān)聽(tīng)指定端口,接收文件數(shù)據(jù)并保存。關(guān)鍵點(diǎn):
- 使用
bind()綁定IP和端口(默認(rèn)端口8888)。 recv()方法接收數(shù)據(jù)流。- 文件以二進(jìn)制模式寫(xiě)入。
import socket
import os
def start_server(host='0.0.0.0', port=8888):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((host, port))
server_socket.listen(1)
print(f"服務(wù)器啟動(dòng),監(jiān)聽(tīng) {host}:{port}")
while True:
client_socket, addr = server_socket.accept()
print(f"連接來(lái)自 {addr}")
# 接收文件名和大小
file_info = client_socket.recv(1024).decode()
file_name, file_size = file_info.split('|')
file_size = int(file_size)
# 創(chuàng)建文件并寫(xiě)入數(shù)據(jù)
with open(file_name, 'wb') as file:
received = 0
while received < file_size:
data = client_socket.recv(4096)
file.write(data)
received += len(data)
print(f"接收進(jìn)度: {received}/{file_size} 字節(jié)")
client_socket.close()
print(f"文件 {file_name} 接收完成")
if __name__ == "__main__":
start_server()
步驟2:Socket客戶(hù)端端(發(fā)送文件)
客戶(hù)端連接到服務(wù)器,發(fā)送文件數(shù)據(jù):
connect()方法指定服務(wù)器IP和端口。- 先發(fā)送文件名和大小元數(shù)據(jù)。
- 分塊讀取文件并發(fā)送,避免內(nèi)存溢出。
import socket
import os
def send_file(server_ip, file_path, port=8888):
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client_socket.connect((server_ip, port))
file_name = os.path.basename(file_path)
file_size = os.path.getsize(file_path)
# 發(fā)送文件信息
client_socket.send(f"{file_name}|{file_size}".encode())
# 分塊發(fā)送文件數(shù)據(jù)
with open(file_path, 'rb') as file:
sent = 0
while sent < file_size:
data = file.read(4096)
client_socket.send(data)
sent += len(data)
print(f"發(fā)送進(jìn)度: {sent}/{file_size} 字節(jié)")
print("文件發(fā)送成功")
except Exception as e:
print(f"錯(cuò)誤: {e}")
finally:
client_socket.close()
步驟3:集成Tkinter GUI
GUI讓工具易用,包含以下元素:
- 輸入框:服務(wù)器IP地址。
- 文件選擇按鈕:使用
filedialog選擇本地文件。 - 進(jìn)度條:顯示傳輸進(jìn)度(基于文件大小)。
- 日志區(qū)域:輸出狀態(tài)信息。
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext
import threading
class FileTransferGUI:
def __init__(self, master):
self.master = master
master.title("局域網(wǎng)文件傳輸工具")
master.geometry("500x400")
# 輸入服務(wù)器IP
tk.Label(master, text="服務(wù)器IP:").pack(pady=5)
self.ip_entry = tk.Entry(master, width=30)
self.ip_entry.pack(pady=5)
self.ip_entry.insert(0, "192.168.1.100") # 默認(rèn)IP,根據(jù)實(shí)際修改
# 文件選擇按鈕
tk.Button(master, text="選擇文件", command=self.select_file).pack(pady=10)
self.file_path = ""
# 發(fā)送按鈕
tk.Button(master, text="發(fā)送文件", command=self.start_send).pack(pady=10)
# 進(jìn)度顯示
self.progress_var = tk.DoubleVar()
self.progress_bar = tk.Progressbar(master, variable=self.progress_var, maximum=100)
self.progress_bar.pack(fill=tk.X, padx=20, pady=10)
# 日志區(qū)域
self.log_area = scrolledtext.ScrolledText(master, height=10)
self.log_area.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
self.log_area.config(state=tk.DISABLED)
def select_file(self):
self.file_path = filedialog.askopenfilename()
if self.file_path:
self.log(f"已選擇文件: {self.file_path}")
def start_send(self):
server_ip = self.ip_entry.get()
if not server_ip or not self.file_path:
messagebox.showerror("錯(cuò)誤", "請(qǐng)輸入IP并選擇文件")
return
# 在新線程中發(fā)送文件,避免GUI凍結(jié)
threading.Thread(target=self.send_file_thread, args=(server_ip, self.file_path)).start()
def send_file_thread(self, server_ip, file_path):
try:
self.log("開(kāi)始發(fā)送文件...")
send_file(server_ip, file_path) # 調(diào)用步驟2的發(fā)送函數(shù)
self.progress_var.set(100)
self.log("文件發(fā)送完成!")
except Exception as e:
self.log(f"錯(cuò)誤: {e}")
def log(self, message):
self.log_area.config(state=tk.NORMAL)
self.log_area.insert(tk.END, message + "\n")
self.log_area.config(state=tk.DISABLED)
self.log_area.yview(tk.END)
if __name__ == "__main__":
root = tk.Tk()
app = FileTransferGUI(root)
root.mainloop()
完整代碼與測(cè)試
整合以上模塊,創(chuàng)建兩個(gè)腳本:
- server.py:運(yùn)行在接收文件的設(shè)備上。
- client_gui.py:運(yùn)行在發(fā)送文件的設(shè)備上,包含GUI。
server.py 完整代碼:
# server.py
import socket
import os
def start_server(host='0.0.0.0', port=8888):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((host, port))
server_socket.listen(1)
print(f"服務(wù)器啟動(dòng),監(jiān)聽(tīng) {host}:{port}")
while True:
client_socket, addr = server_socket.accept()
print(f"連接來(lái)自 {addr}")
# 接收文件信息
file_info = client_socket.recv(1024).decode()
file_name, file_size = file_info.split('|')
file_size = int(file_size)
# 寫(xiě)入文件
with open(file_name, 'wb') as file:
received = 0
while received < file_size:
data = client_socket.recv(4096)
file.write(data)
received += len(data)
print(f"接收進(jìn)度: {received}/{file_size} 字節(jié)")
client_socket.close()
print(f"文件 {file_name} 接收完成")
if __name__ == "__main__":
start_server()
client_gui.py 完整代碼:
# client_gui.py
import socket
import os
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext
import threading
def send_file(server_ip, file_path, port=8888):
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client_socket.connect((server_ip, port))
file_name = os.path.basename(file_path)
file_size = os.path.getsize(file_path)
# 發(fā)送文件元數(shù)據(jù)
client_socket.send(f"{file_name}|{file_size}".encode())
# 分塊發(fā)送
with open(file_path, 'rb') as file:
sent = 0
while sent < file_size:
data = file.read(4096)
client_socket.send(data)
sent += len(data)
print(f"發(fā)送進(jìn)度: {sent}/{file_size} 字節(jié)")
print("文件發(fā)送成功")
except Exception as e:
print(f"錯(cuò)誤: {e}")
finally:
client_socket.close()
class FileTransferGUI:
def __init__(self, master):
self.master = master
master.title("局域網(wǎng)文件傳輸工具")
master.geometry("500x400")
# 輸入服務(wù)器IP
tk.Label(master, text="服務(wù)器IP:").pack(pady=5)
self.ip_entry = tk.Entry(master, width=30)
self.ip_entry.pack(pady=5)
self.ip_entry.insert(0, "192.168.1.100") # 修改為實(shí)際接收端IP
# 文件選擇
tk.Button(master, text="選擇文件", command=self.select_file).pack(pady=10)
self.file_path = ""
# 發(fā)送按鈕
tk.Button(master, text="發(fā)送文件", command=self.start_send).pack(pady=10)
# 進(jìn)度條
self.progress_var = tk.DoubleVar()
self.progress_bar = tk.Progressbar(master, variable=self.progress_var, maximum=100)
self.progress_bar.pack(fill=tk.X, padx=20, pady=10)
# 日志
self.log_area = scrolledtext.ScrolledText(master, height=10)
self.log_area.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
self.log_area.config(state=tk.DISABLED)
def select_file(self):
self.file_path = filedialog.askopenfilename()
if self.file_path:
self.log(f"已選擇文件: {self.file_path}")
def start_send(self):
server_ip = self.ip_entry.get()
if not server_ip or not self.file_path:
messagebox.showerror("錯(cuò)誤", "請(qǐng)輸入IP并選擇文件")
return
threading.Thread(target=self.send_file_thread, args=(server_ip, self.file_path)).start()
def send_file_thread(self, server_ip, file_path):
try:
self.log("開(kāi)始發(fā)送文件...")
send_file(server_ip, file_path)
self.progress_var.set(100)
self.log("文件發(fā)送完成!")
except Exception as e:
self.log(f"錯(cuò)誤: {e}")
def log(self, message):
self.log_area.config(state=tk.NORMAL)
self.log_area.insert(tk.END, message + "\n")
self.log_area.config(state=tk.DISABLED)
self.log_area.yview(tk.END)
if __name__ == "__main__":
root = tk.Tk()
app = FileTransferGUI(root)
root.mainloop()
測(cè)試與使用指南
準(zhǔn)備工作:
- 確保所有設(shè)備在同一局域網(wǎng)。
- 在接收文件的設(shè)備上運(yùn)行
server.py(命令行:python server.py)。 - 在發(fā)送文件的設(shè)備上運(yùn)行
client_gui.py(命令行:python client_gui.py)。
操作步驟:
- 在GUI中輸入接收端IP(默認(rèn)為192.168.1.100,根據(jù)實(shí)際修改)。
- 點(diǎn)擊“選擇文件”選取本地文件。
- 點(diǎn)擊“發(fā)送文件”,觀察進(jìn)度條和日志。
測(cè)試用例:
- 發(fā)送小文件(如文本文件):驗(yàn)證基本功能。
- 發(fā)送大文件(如視頻):測(cè)試穩(wěn)定性和進(jìn)度更新。
- 錯(cuò)誤處理:輸入錯(cuò)誤IP或中斷連接,檢查日志輸出。
優(yōu)化建議:
- 添加文件接收確認(rèn)機(jī)制。
- 支持多文件隊(duì)列傳輸。
- 加密數(shù)據(jù)以增強(qiáng)安全性。
結(jié)語(yǔ)
通過(guò)這款工具,你將深入理解Python的Socket編程和GUI開(kāi)發(fā)核心。僅用200行代碼就能實(shí)現(xiàn)實(shí)用的文件傳輸功能。未來(lái)還可以擴(kuò)展更多功能,比如文件夾同步或跨平臺(tái)兼容性。代碼已在真實(shí)局域網(wǎng)環(huán)境中測(cè)試,運(yùn)行穩(wěn)定高效??靵?lái)親身體驗(yàn),讓文件共享變得更輕松!
以上就是基于Python實(shí)現(xiàn)局域網(wǎng)文件傳輸工具的詳細(xì)內(nèi)容,更多關(guān)于Python文件傳輸?shù)馁Y料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python-tkinter之按鈕的使用,開(kāi)關(guān)方法
今天小編就為大家分享一篇python-tkinter之按鈕的使用,開(kāi)關(guān)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06
tensorflow之tf.record實(shí)現(xiàn)存浮點(diǎn)數(shù)數(shù)組
今天小編就為大家分享一篇tensorflow之tf.record實(shí)現(xiàn)存浮點(diǎn)數(shù)數(shù)組,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
Python超有趣實(shí)例通過(guò)冒泡排序來(lái)實(shí)現(xiàn)LOL厄斐琉斯控槍
冒泡排序是一種簡(jiǎn)單的排序算法,它也是一種穩(wěn)定排序算法。其實(shí)現(xiàn)原理是重復(fù)掃描待排序序列,并比較每一對(duì)相鄰的元素,當(dāng)該對(duì)元素順序不正確時(shí)進(jìn)行交換。一直重復(fù)這個(gè)過(guò)程,直到?jīng)]有任何兩個(gè)相鄰元素可以交換,就表明完成了排序2022-05-05
python中的turtle庫(kù)函數(shù)簡(jiǎn)單使用教程
這篇文章主要介紹了python中的turtle庫(kù)函數(shù)簡(jiǎn)單使用教程。本文通過(guò)圖片的形式給大家展示的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-07-07
Python數(shù)據(jù)結(jié)構(gòu)與算法之常見(jiàn)的分配排序法示例【桶排序與基數(shù)排序】
這篇文章主要介紹了Python數(shù)據(jù)結(jié)構(gòu)與算法之常見(jiàn)的分配排序法,結(jié)合實(shí)例形式分析了桶排序與基數(shù)排序的相關(guān)原理及實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-12-12
python opencv通過(guò)4坐標(biāo)剪裁圖片
圖片剪裁是常用的方法,那么如何通過(guò)4坐標(biāo)剪裁圖片,本文就詳細(xì)的來(lái)介紹一下,感興趣的小伙伴們可以參考一下2021-06-06
python文件夾分區(qū)的實(shí)現(xiàn)方法實(shí)例
這篇文章主要給大家介紹了關(guān)于python文件夾分區(qū)的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04

