# server.py 服务端
import os
import socketserver
class Server(socketserver.BaseRequestHandler):
server_file_path = "F:/patch"
def get_server_files(self):
for root, dirs, files in os.walk(self.server_file_path):
return files
def get_file_context(self, file_name):
try:
with open(self.server_file_path + "/" + file_name, "rb") as file:
data = file.read()
return data
except:
return "请求文件不存在"
def handle(self):
print("Connection: ", self.client_address)
file_string = ",".join(self.get_server_files())
while True:
message = self.request.recv(1024)
if not message:
break
# 动作判断
if message.decode() == "__file_list__":
# 发送文件列表
self.request.send(bytes(file_string, "UTF-8"))
else:
# 发送文件数据
data = self.get_file_context(message.decode())
self.request.send(data)
if __name__ == '__main__':
host, port = "127.0.0.1", 8080
server = socketserver.ThreadingTCPServer((host, port), Server)
server.serve_forever()
# SocketDownload.py 下载线程
import socket
import threading
class SocketDownload(threading.Thread):
server_ip = "127.0.0.1"
server_port = 8080
def __init__(self, file_name, file_save_path):
threading.Thread.__init__(self)
self.file_name = file_name
self.file_save_path = file_save_path
def run(self):
address = (self.server_ip, self.server_port)
sk = socket.socket()
sk.connect(address)
while True:
sk.send(bytes(self.file_name, "utf-8"))
msg = sk.recv(1024)
if msg:
with open(self.file_save_path + "/" + self.file_name, "wb") as f:
f.write(msg)
print(self.file_name + ": 下载成功,保存路径:" + self.file_save_path)
break
sk.close()
# DownloadSurface 客户端界面
import socket
import tkinter as tk
from tkinter.filedialog import *
from MutilFile.client.SocketDownload import SocketDownload
class DownloadSurface(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master=None)
self.grid()
self.create_widgets()
def create_widgets(self):
# row 0
self.lbIpPort = tk.Label(self, text="IP & 端口")
self.lbIpPort.grid(row=0, column=0)
self.defaultIpStringVar = StringVar()
self.defaultIpStringVar.set("127.0.0.1")
self.entryIp = tk.Entry(self, textvariable=self.defaultIpStringVar)
self.entryIp.grid(row=0, column=1)
self.defaultPortStringVar = StringVar()
self.defaultPortStringVar.set("8080")
self.entryPort = tk.Entry(self, textvariable=self.defaultPortStringVar)
self.entryPort.grid(row=0, column=2)
self.btnConn = tk.Button(self, text="连接服务器", command=self.connect_server)
self.btnConn.grid(row=0, column=3)
# row 1
self.lbSavePath = tk.Label(self, text="保存路径")
self.lbSavePath.grid(row=1, column=0)
self.savePathStringVar = StringVar()
self.savePathStringVar.set("F:/patch")
self.entrySavePath = tk.Entry(self, textvariable=self.savePathStringVar, width=40)
self.entrySavePath.grid(row=1, column=1, columnspan=2)
self.btnSelSavePath = tk.Button(self, text="选择文件夹", command=self.select_save_path)
self.btnSelSavePath.grid(row=1, column=3)
# row 2
self.lbServerFile = tk.Label(self, text="服务端文件列表")
self.lbServerFile.grid(row=2, column=1)
self.listboxServerFile = tk.Listbox(self, width=10, height=6)
self.listboxServerFile.grid(row=3, column=1, rowspan=5)
self.btnToRight = tk.Button(self, text=" > ", command=self.add_to_download)
self.btnToRight.grid(row=8, column=1)
self.btnToLeft = tk.Button(self, text=" < ", command=self.cancel_download)
self.btnToLeft.grid(row=8, column=2)
self.listboxDownloadFile = tk.Listbox(self, width=10, height=6)
self.listboxDownloadFile.grid(row=3, column=2, rowspan=5)
self.lbDownloadFile = tk.Label(self, text="文件下载列表")
self.lbDownloadFile.grid(row=2, column=2)
# row 3
self.btnConn = tk.Button(self, text="开始下载", command=self.download)
self.btnConn.grid(row=2, column=3)
def connect_server(self):
self.listboxDownloadFile.delete(0, END)
self.listboxServerFile.delete(0, END)
ip_port = (self.entryIp.get(), int(self.entryPort.get()))
print(ip_port)
sk = socket.socket()
sk.connect(ip_port)
sk.send(bytes("__file_list__", "utf-8"))
msg = str(sk.recv(1024), "UTF-8").split(",")
for item in msg:
self.listboxServerFile.insert(tk.END, item)
sk.close()
def select_save_path(self):
file = askdirectory(title="选择下载文件保存路径")
self.savePathStringVar.set(file)
def add_to_download(self):
for item in self.listboxServerFile.curselection():
self.listboxDownloadFile.insert(tk.END, self.listboxServerFile.get(item))
self.listboxServerFile.delete(item)
def cancel_download(self):
for item in self.listboxDownloadFile.curselection():
self.listboxServerFile.insert(tk.END, self.listboxDownloadFile.get(item))
self.listboxDownloadFile.delete(item)
def download(self):
print("开始下载")
fileCount = self.listboxDownloadFile.size()
thread = []
for i in range(0, fileCount):
print(self.listboxDownloadFile.get(i))
print(self.entrySavePath.get())
thread.append(SocketDownload(self.listboxDownloadFile.get(i), self.entrySavePath.get()))
# 开启多线程
for i in range(0, len(thread)):
thread[i].start()
def init_window(root):
sw = root.winfo_screenwidth()
# 得到屏幕宽度
sh = root.winfo_screenheight()
# 得到屏幕高度
ww = 480
wh = 450
# 窗口宽高为100
x = (sw - ww) / 2
y = (sh - wh) / 2
root.geometry("%dx%d+%d+%d" % (ww, wh, x - 200, y))
root = tk.Tk()
root.title("多文件下载器")
init_window(root)
app = DownloadSurface(master=root)
app.mainloop()