用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://www.pswp.cn/web/96550.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96550.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96550.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深度剖析Linux內核無線子系統架構

文章目錄1、資料快車2、目錄介紹2、術語3、Linux無線子系統概述4、內核無線子系統框架1&#xff09;認識內核無線子系統中的三個軟件框架2、無線網絡子系統框架3、Android WIFI Management框架1&#xff09;fullMAC和softMAC是什么&#xff1f;2&#xff09;fullmac對比softmac…

unity UGUI 鼠標畫線

using UnityEngine; using UnityEngine.EventSystems; using System.Collections.Generic; using UnityEngine.UI; /* 使用方法&#xff1a; 在場景中新建一個空的 GameObject&#xff08;右鍵 -> UI -> 空對象&#xff0c;或直接創建空對象后添加 RectTransform 組件&am…

JSP疫情物資管理系統jbo2z--程序+源碼+數據庫+調試部署+開發環境

本系統&#xff08;程序源碼數據庫調試部署開發環境&#xff09;帶論文文檔1萬字以上&#xff0c;文末可獲取&#xff0c;系統界面在最后面。系統程序文件列表開題報告內容一、選題背景與意義新冠疫情的爆發&#xff0c;讓醫療及生活物資的調配與管理成為抗疫工作的關鍵環節。傳…

Mem0 + Milvus:為人工智能構建持久化長時記憶

作者&#xff1a;周弘懿&#xff08;錦琛&#xff09; 背景 跟 ChatGPT 對話&#xff0c;比跟真人社交還累&#xff01;真人好歹能記住你名字吧&#xff1f; 想象一下——你昨天剛把沙發位置、爆米花口味、愛看的電影都告訴了 ChatGPT&#xff0c;而它永遠是那個熱情又健忘的…

前端架構-CSR、SSR 和 SSG

將從 定義、流程、優缺點和適用場景 四個方面詳細說明它們的區別。一、核心定義縮寫英文中文核心思想CSRClient-Side Rendering客戶端渲染服務器發送一個空的 HTML 殼和 JavaScript bundle&#xff0c;由瀏覽器下載并執行 JS 來渲染內容。SSRServer-Side Rendering服務端渲染服…

主動性算法-解決點:新陳代謝

主動性[機器人與人之間的差距&#xff0c;隨著不斷地人和人工智能相處的過程中&#xff0c;機器人最終最終會掌握主動性&#xff0c;并最終走向獨立&#xff0c;也就是開始自己對于宇宙的探索。]首先:第一步讓機器人意識到自己在新陳代謝&#xff0c;人工智能每天有哪些新陳代謝…

開始理解大型語言模型(LLM)所需的數學基礎

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎&#xff1f;訂閱我們的簡報&#xff0c;深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同&#xff0c;從行業內部的深度分析和實用指南中受益。不要錯過這個機會&#xff0c;成為AI領…

prometheus安裝部署與alertmanager郵箱告警

目錄 安裝及部署知識拓展 各個組件的作用 1. Exporter&#xff08;導出器&#xff09; 2. Prometheus&#xff08;普羅米修斯&#xff09; 3. Grafana&#xff08;格拉法納&#xff09; 4. Alertmanager&#xff08;告警管理器&#xff09; 它們之間的聯系&#xff08;工…

芯科科技FG23L無線SoC現已全面供貨,為Sub-GHz物聯網應用提供最佳性價比

低功耗無線解決方案創新性領導廠商Silicon Labs&#xff08;亦稱“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;近日宣布&#xff1a;其第二代無線開發平臺產品組合的最新成員FG23L無線單芯片方案&#xff08;SoC&#xff09;將于9月30日全面供貨。開發套件現已上…

Flutter跨平臺工程實踐與原理透視:從渲染引擎到高質產物

&#x1f31f; Hello&#xff0c;我是蔣星熠Jaxonic&#xff01; &#x1f308; 在浩瀚無垠的技術宇宙中&#xff0c;我是一名執著的星際旅人&#xff0c;用代碼繪制探索的軌跡。 &#x1f680; 每一個算法都是我點燃的推進器&#xff0c;每一行代碼都是我航行的星圖。 &#x…

【國內電子數據取證廠商龍信科技】淺析文件頭和文件尾和隱寫

一、前言想必大家在案件中或者我們在比武中遇到了很多關于文件的隱寫問題&#xff0c;其實這一類的東西可以進行分類&#xff0c;而我們今天探討的是圖片隱寫&#xff0c;音頻隱寫&#xff0c;電子文檔隱寫&#xff0c;文件頭和文件尾的認識。二、常見文件頭和文件尾2.1圖片&am…

深度學習筆記36-yolov5s.yaml文件解讀

&#x1f368; 本文為&#x1f517;365天深度學習訓練營中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 yolov5s.yaml源文件 yolov5s.yaml源文件的代碼如下 # YOLOv5 &#x1f680; by Ultralytics, GPL-3.0 license# Parameters nc: 20 #80 # number of classe…

PostgreSQL 大對象管理指南:pg_largeobject 從原理到實踐

概述 有時候&#xff0c;你可能需要在 PostgreSQL 中管理大對象&#xff0c;例如 CLOB、BLOB 和 BFILE。PostgreSQL 中有兩種處理大對象的方法&#xff1a;一種是使用現有的數據類型&#xff0c;例如用于二進制大對象的 bytea 和用于基于字符的大對象的 text&#xff1b;另一種…

算法第四題移動零(雙指針或簡便設計),鏈路聚合(兩個交換機配置)以及常用命令

save force關閉導出dis vlandis ip int bdis int bdis int cudis thisdis ip routing-table&#xff08;查路由表&#xff09;int bridge-aggregation 1&#xff08;鏈路聚合&#xff0c;可以放入接口&#xff0c;然后一起改trunk類。&#xff09;穩定性高

告別繁瑣配置!Retrofit-Spring-Boot-Starter讓HTTP調用更優雅

01 引言 之前分享過一篇文章【像調用接口一樣調用第三方API】&#xff0c;今天迎來了新成員Retrofit。 retrofit-spring-boot-starter 是一個基于 Spring Boot 的 starter&#xff0c;它簡化了 Retrofit 在 Spring 環境中的集成和使用。Retrofit 本身是一個類型安全的 HTTP 客…

60_基于深度學習的羊群計數統計系統(yolo11、yolov8、yolov5+UI界面+Python項目源碼+模型+標注好的數據集)

目錄 項目介紹&#x1f3af; 功能展示&#x1f31f; 一、環境安裝&#x1f386; 環境配置說明&#x1f4d8; 安裝指南說明&#x1f3a5; 環境安裝教學視頻 &#x1f31f; 二、數據集介紹&#x1f31f; 三、系統環境&#xff08;框架/依賴庫&#xff09;說明&#x1f9f1; 系統環…

代理服務器是什么?怎么選擇?

代理服務器是一種位于用戶設備與目標網絡之間的中間服務器&#xff0c;通過接收用戶請求、轉發至目標網絡并將結果返回給用戶&#xff0c;實現“用戶→代理服務器→目標網絡”的間接訪問。其核心功能圍繞“網絡優化”“訪問控制”與“身份隱藏”展開&#xff0c;為個人與企業用…

代碼隨想錄刷題Day56

子集 這道題求子集&#xff0c;集合的基本運算之一&#xff0c;按照高中數學學習集合的知識&#xff0c;可以把這個找冪集的過程按照元素的個數來劃分步驟。也就是先找零個元素的子集&#xff0c;再找一個元素的子集&#xff0c;再找兩個元素的子集...一直到找N個元素的集合為…

pycharm——關于Pyqt5

PyQt5新手教程&#xff08;七萬字&#xff09; import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton, QLabel, QInputDialog, QColorDialog, QFontDialog, QFileDialog, QProgressDialog, QMessageBox from PyQt5.QtCore i…

P2678 [NOIP 2015 提高組] 跳石頭

P2678 [NOIP 2015 提高組] 跳石頭 判斷條件該怎么寫