当前位置: 首页 > news >正文

用python的socket写一个局域网传输文件的程序

局域网传输文件是最最常用的功能,我参考https://www.jb51.net/python/345837qrz.htm这篇文章,复制粘贴,开发了一个。但发现进度条没有用,也没有显示传输用时和传输速度的功能,于是我改写了代码,使它实现这个功能。

import socket
import osdef start_server(host='192.168.1.145', port=8888):server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind((host, port))server_socket.listen(1)print(f"服务器启动,监听 {host}:{port}")while True:client_socket, addr = server_socket.accept()print(f"连接来自 {addr}")# 接收文件名和大小file_info = client_socket.recv(1024).decode()file_name, file_size = file_info.split('|')file_size = int(file_size)# 创建文件并写入数据with open('d:/socketfile/'+file_name, 'wb') as file:received = 0while received < file_size:data = client_socket.recv(4096)file.write(data)received += len(data)print(f"接收进度: {received}/{file_size} 字节")client_socket.close()print(f"文件 {file_name} 接收完成")if __name__ == "__main__":start_server()

上面是服务器端,没有怎么改,增加了'd:/socketfile/'+file_name,把文件放在我们想要放的文件夹。

# -*- coding: utf-8 -*-
"""
Created on Mon Sep  8 14:31:28 2025@author: YBK
"""import socket
import os
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext
import threading
from tkinter import ttk
import timeclass FileTransferGUI:def __init__(self, master):self.master = mastermaster.title("局域网文件传输工具")master.geometry("500x400")# 输入服务器IPtk.Label(master, text="服务器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.145")  # 默认IP,根据实际修改#发生使用时间、传输速度self.usetime = 0self.sudu = 0# 文件选择按钮tk.Button(master, text="选择文件", command=self.select_file).pack(pady=10)self.file_path = ""# 发送按钮tk.Button(master, text="发送文件", command=self.start_send).pack(pady=10)# 进度显示self.progress_var = tk.DoubleVar()self.progress_bar = ttk.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 send_file(self,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)# 发送文件信息client_socket.send(f"{file_name}|{file_size}".encode())# 分块发送文件数据with open(file_path, 'rb') as file:sent = 0start = time.time()while sent < file_size:data = file.read(4096)client_socket.send(data)sent += len(data)# print(f"发送进度: {sent}/{file_size} 字节")self.progress_var.set(int(sent/file_size*100))self.usetime = time.time() - startself.sudu = file_size / 1024 / 1024 / self.usetimeprint(f"文件发送成功,耗时{self.usetime:.2f}秒,速度:{self.sudu:.2f}m/s")except Exception as e:print(f"错误: {e}")finally:client_socket.close()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("错误", "请输入IP并选择文件")return# 在新线程中发送文件,避免GUI冻结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("开始发送文件...")self.send_file(server_ip, file_path)  # 调用步骤2的发送函数self.progress_var.set(100)self.log(f"文件发送完成!耗时{self.usetime:.4f}秒,速度:{self.sudu:.2f}m/s")except Exception as e:self.log(f"错误: {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()

以上就改动比较大,也让我慢慢熟悉面向对象编程,用self.可以为公用变量,增加时间和速度的显示,原来代码出现tk.Progressbar报错,进度条无法正常显示等问题。

速度还是可以的。

用一段时间,感觉还是不爽,要开2个程序,一个是服务器端,一个是客户端,才能在2台电脑中互传文件,为此,我把它一体化,只要用一个程序就实现了服务器端和客户端的功能,又能接受文件,又能发送文件。同时,加上我一直喜欢用的拖放功能,不能每次去选择文件传输。

# -*- coding: utf-8 -*-
"""
Created on Mon Sep  8 14:31:28 2025@author: YBK
"""import socket
import os
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext
import threading
from tkinter import ttk
import time
import windnd
from tkinter import LabelFrame
import chardetdef start_server(host='192.168.1.140', port=8888):server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind((host, port))server_socket.listen(1)print(f"服务器启动,监听 {host}:{port}")while True:client_socket, addr = server_socket.accept()print(f"连接来自 {addr}")# 接收文件名和大小raw_data = client_socket.recv(1024)encoding = chardet.detect(raw_data)['encoding']file_info = raw_data.decode(encoding)file_name, file_size = file_info.split('|')file_size = int(file_size)# 创建文件并写入数据with open('e:/socketfile/'+file_name, 'wb') as file:received = 0while received < file_size:data = client_socket.recv(4096)file.write(data)received += len(data)print(f"接收进度: {received}/{file_size} 字节")client_socket.close()print(f"文件 {file_name} 接收完成")class FileTransferGUI:def __init__(self, master):self.master = mastermaster.title("局域网文件传输工具")master.geometry("500x600")# 输入服务器IPtk.Label(master, text="服务器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.145")  # 默认IP,根据实际修改tk.Label(master, text="本机IP(作为服务器):").pack(pady=5)self.bip_entry = tk.Entry(master, width=30)self.bip_entry.pack(pady=5)self.bip_entry.insert(0, "192.168.1.140")  # 默认IP,根据实际修改# 启动服务器按钮self.bt_fwq = tk.Button(master, text="启动服务器", command=self.start_fwq)self.bt_fwq.pack(pady=10)#发生使用时间self.usetime = 0self.sudu = 0# 文件选择按钮tk.Button(master, text="选择文件", command=self.select_file).pack(pady=10)self.file_path = ""# 文件拖放区域self.f_frame = LabelFrame(master, text="也可以拖放文件到此", width=250)self.f_frame.pack(expand=True, padx=10)self.label1 = tk.Label(self.f_frame,wraplength=580,text="")self.label1.pack(anchor="w", pady=5)windnd.hook_dropfiles(self.f_frame, func=self.handle_file)# 发送按钮tk.Button(master, text="发送文件", command=self.start_send).pack(pady=10)# 进度显示self.progress_var = tk.DoubleVar()self.progress_bar = ttk.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 start_server(self,host='192.168.1.140', port=8888):server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind((host, port))server_socket.listen(1)print(f"服务器启动,监听 {host}:{port}")while True:client_socket, addr = server_socket.accept()print(f"连接来自 {addr}")# 接收文件名和大小raw_data = client_socket.recv(1024)encoding = chardet.detect(raw_data)['encoding']file_info = raw_data.decode(encoding)file_name, file_size = file_info.split('|')file_size = int(file_size)# 创建文件并写入数据with open('e:/socketfile/'+file_name, 'wb') as file:received = 0while received < file_size:data = client_socket.recv(4096)file.write(data)received += len(data)print(f"接收进度: {received}/{file_size} 字节")client_socket.close()print(f"文件 {file_name} 接收完成")self.log(f"文件 {file_name} 接收完成")def handle_file(self,files):if len(files) > 0:path = files[0].decode('gbk').replace('\\', '/')self.file_path = pathif self.file_path:self.log(f"已选择文件: {self.file_path}")def start_fwq(self):fwq_ip = self.bip_entry.get()if not fwq_ip:messagebox.showerror("错误", "请输入IP并选择文件")return# print(fwq_ip)# 在新线程中发送文件,避免GUI冻结threading.Thread(target=self.start_server, args=(fwq_ip, 8888)).start()self.bt_fwq.config(state="disabled", bg="lightgray")def send_file(self,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)# 发送文件信息client_socket.send(f"{file_name}|{file_size}".encode())# 分块发送文件数据with open(file_path, 'rb') as file:sent = 0start = time.time()while sent < file_size:data = file.read(4096)client_socket.send(data)sent += len(data)# print(f"发送进度: {sent}/{file_size} 字节")self.progress_var.set(int(sent/file_size*100))self.usetime = time.time() - startself.sudu = file_size / 1024 / 1024 / self.usetimeprint(f"文件发送成功,耗时{self.usetime:.2f}秒,速度:{self.sudu:.2f}m/s")except Exception as e:print(f"错误: {e}")finally:client_socket.close()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("错误", "请输入IP并选择文件")return# 在新线程中发送文件,避免GUI冻结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("开始发送文件...")self.send_file(server_ip, file_path)  # 调用步骤2的发送函数self.progress_var.set(100)self.log(f"文件发送完成!耗时{self.usetime:.4f}秒,速度:{self.sudu:.2f}m/s")except Exception as e:self.log(f"错误: {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()

填好ip,点击启动服务器就可以接收文件。下面还能显示接收到的文件。


文章转载自:

http://vI2zLnVI.jfcbs.cn
http://UzNWUYeh.jfcbs.cn
http://srPtg7V6.jfcbs.cn
http://pXlCIfdW.jfcbs.cn
http://GSvRcBaW.jfcbs.cn
http://rNeVqKnN.jfcbs.cn
http://F2OewvFn.jfcbs.cn
http://kjtnqC45.jfcbs.cn
http://MVvD4PE5.jfcbs.cn
http://ckk7KbOC.jfcbs.cn
http://Z8p31XkU.jfcbs.cn
http://kcGWo1Zu.jfcbs.cn
http://JpCnHEtF.jfcbs.cn
http://98oPZUEh.jfcbs.cn
http://k1q9Zquf.jfcbs.cn
http://UimaM8Ny.jfcbs.cn
http://UyvFtYHT.jfcbs.cn
http://HFxuWebm.jfcbs.cn
http://OWEjRs75.jfcbs.cn
http://WjFMxBoz.jfcbs.cn
http://5YJlkjNY.jfcbs.cn
http://AchBcATM.jfcbs.cn
http://lhHDpOVx.jfcbs.cn
http://9m1hpqM5.jfcbs.cn
http://7FbuPGJw.jfcbs.cn
http://rMIpOWj5.jfcbs.cn
http://kB7nKxu3.jfcbs.cn
http://cynK7byk.jfcbs.cn
http://UaL5b143.jfcbs.cn
http://OSPfWPSI.jfcbs.cn
http://www.dtcms.com/a/380058.html

相关文章:

  • CentOS配置vsftpd服务器
  • 华为初级认证培训需要吗?HCIA考试考什么内容?自学还是报班?
  • 系统核心解析:深入操作系统内部机制——进程管理与控制指南(二)【进程状态】
  • KafKa02:Kafka配置文件server.properties介绍
  • 【LeetCode 每日一题】3459. 最长 V 形对角线段的长度
  • Linux系统之----信号中断(下)
  • 【C++】模板进阶:非类型参数、模板特化与分离编译
  • 使用OmniAvatar-14B模型实现照片和文字生成视频的完整指南
  • Redis缓存雪崩
  • 复习Git在IDEA中的关键操作
  • IntelliJ IDEA git凭据帮助程序
  • 【Docker】P3 入门指南:运维与开发双重视角
  • Mac安装hadoop
  • 租房平台|租房管理平台小程序系统|基于java的租房系统 设计与实现(源码+数据库+文档)
  • Linux 深入理解权限
  • SQL Server 中的 STUFF 函数与FOR XML PATH详解
  • 配置自签证书多域名的动态网站+部署http的repo仓库+基于nfs与yum仓库的http部署
  • React学习教程,从入门到精通,React AJAX 语法知识点与案例详解(18)
  • Go语言详细指南:特点、应用场景与开发工具
  • vue el-cascader级联选择器-地区三级选择问题记录
  • 《机器人抓取:从经典到现代的综述》内容的提取和凝练:
  • 【ZEGO即构开发者日报】微信公众号上线“智能回复”功能;2025年8月中国应用/游戏厂商出海收入Top30榜;土耳其宣布将封禁29款社交/社媒应用……
  • qt QAreaLegendMarker详解
  • #C语言——刷题攻略:牛客编程入门训练(十三):循环输出图形(二)、一维数组(一),轻松拿捏!
  • Nginx服务——安装与搭建
  • 远程真机调试支持网络多线路切换,让自助兼容性测试更流畅
  • AI Agent工作流实用手册:5种常见模式的实现与应用,助力生产环境稳定性
  • 前端渲染技术全解析:SSR、SSG、CSR 有什么区别?
  • html css js网页制作成品——HTML+CSS娃娃店网页设计(4页)附源码
  • mac本地安装mysql