

“嘿,隔壁工位的小明又拿着U盘来找你拷‘学习资料’?别再插来插去了!今天咱们写一个10秒建站的小工具,让你的电脑秒变‘私人网盘’:插上网线、点开脚本、隔壁小姐姐就能用浏览器愉快地下载你的‘学习资料’,还带密码锁,防老王,防老板,防熊孩子!全程只需一个 Python 文件,零依赖、零配置、零吐槽——妈妈再也不用担心我不会搭服务器啦!”
┌-------------------------------┐│ FileSharingGUI │ ← 负责貌美如花(tk 界面)├-------------┬-----------------┤│ FileSharingServer │ ← 负责赚钱养家(socket 服务)├-------------┴-----------------┤│ AuthHTTPRequestHandler │ ← 负责安保(Basic Auth)└-------------------------------┘__main__ 启动 FileSharingGUI。FileSharingGUI 创建 FileSharingServer 实例。FileSharingServer 在独立线程中跑 socketserver.TCPServer,并把请求交给 AuthHTTPRequestHandler。AuthHTTPRequestHandler 继承 http.server.SimpleHTTPRequestHandler,在 do_GET 里加料做认证。if __name__ == "__main__": root = tk.Tk() app = FileSharingGUI(root) root.mainloop()FileSharingGUI 这个“装修队”,让它贴瓷砖、打柜子。 | |
classFileSharingServer:def__init__(self, gui): self.gui = gui # 回调 GUI 写日志 self.server = None# socketserver.TCPServer 实例 self.server_thread = None# 子线程句柄 self.running = False# 状态机:跑 or 躺accept() 的 TCP 服务器。start() 方法defstart(self, directory, port, username, password):if self.running:returnFalse os.chdir(directory) # 切换到共享目录,后续 SimpleHTTPRequestHandler 直接读文件 handler_class = partial( AuthHTTPRequestHandler, username=username orNone, password=password orNone ) socketserver.TCPServer.allow_reuse_address = Truetry: self.server = socketserver.TCPServer(("", port), handler_class) self.server.log_callback = self.gui.add_log # 打通日志 ...partial:把 username、password 提前塞进 AuthHTTPRequestHandler 的构造函数,优雅省事。allow_reuse_address = True:防止“端口被占用”惨案。stop() 方法defstop(self):if self.running and self.server: self.server.shutdown() # 停止 serve_forever self.server.server_close() # 关 socket self.running = False self.server_thread.join() # 等线程优雅退出shutdown() 会跳出 serve_forever 的循环,线程自然结束。def__init__(self, *args, username=None, password=None, **kwargs): self.username = username self.password = password super().__init__(*args, **kwargs)do_GET 要用。defdo_AUTHHEAD(self): self.send_response(401) self.send_header('WWW-Authenticate', 'Basic realm="File Sharing"') self.send_header('Content-type', 'text/html') self.end_headers()WWW-Authenticate 头就会弹登录框。defdo_GET(self):if self.username and self.password: auth_header = self.headers.get('Authorization')ifnot auth_header: self.do_AUTHHEAD(); return auth_type, auth_data = auth_header.split(maxsplit=1)if auth_type.lower() != 'basic': self.do_AUTHHEAD(); return username, password = base64.b64decode(auth_data).decode().split(':', 1)if username != self.username or password != self.password: self.do_AUTHHEAD(); return# 认证通过,父类接管 super().do_GET()deflog_message(self, fmt, *args):if hasattr(self.server, 'log_callback'): self.server.log_callback(fmt % args)def__init__(self, root): self.root = root self.root.title("局域网文件共享工具") self.root.geometry("700x500") self.server = FileSharingServer(self) # 创建发动机用 ttk.LabelFrame 把界面切成四大块:
defbrowse_directory(self): directory = filedialog.askdirectory()if directory: self.shared_directory = directory self.dir_entry.delete(0, tk.END) self.dir_entry.insert(0, directory)filedialog.askdirectory() 调出系统文件夹选择器,比手动输入路径优雅一万倍。defstart_server(self): directory = self.dir_entry.get().strip()ifnot os.path.isdir(directory): messagebox.showerror("错误", "请选择有效的共享目录")return ...local_ip = self.ip_label.cget("text")self.url_label.config(text=f"http://{local_ip}:{port}")self.server_thread = threading.Thread(target=self.server.serve_forever)self.server_thread.daemon = Trueself.server_thread.start()daemon=True:主线程退出时子线程陪葬,防止关不掉。defadd_log(self, message): self.log_text.config(state=tk.NORMAL) self.log_text.insert(tk.END, message + "\n") self.log_text.see(tk.END) self.log_text.config(state=tk.DISABLED)DISABLED,防止用户手滑删掉日志;写之前先 NORMAL,写完再关。pyinstaller -F -w share_server.py 生成无控制台 exe,双击即用。os.chdir 对中文支持良好,但终端编码不对时日志会乱码,可 chcp 65001。把脚本丢进 U 盘,下次去丈母娘家,插上电脑就能分享婚纱照——程序员浪漫起来,连网线都在冒粉红泡泡!
点击【关注+收藏】获取最新的实战代码案例
用Python打造汉字笔画查询工具:从GUI界面到笔顺动画实现
Python超实用 Markdown 转富文本神器 —— 代码全解析
【实战1】
【实战2】
【实战3】
【实战4】

