一主界面:

**二:发送文件界面:**首先需要开启发送文件服务端(这里需要注意的是每一次发送文件之前都需要开启一次服务端,因为我在这里将每一次发送文件之后就关闭了客户端和服务端之间的连接)

输出相关客户端和服务端的文件传输过程中的信息:

如果发送文件没有选择,将会得到提示“请选择发送文件”

三:下载文件主界面:首先需要开启下载文件服务端(同样,这里需要注意的是每一次发送文件之前都需要开启一次服务端,因为我在这里将每一次发送文件之后就关闭了客户端和服务端之间的连接)
注意:这里的下载文件的思路:
1.当开启下载服务端之后,客户端选择要下载的文件
2.客户端将要下载的文件路径发送给服务端
3.服务端根据客户端发送来的文件路径,将要发送的文件大小,类型,文件名打包为消息头发送给客户端
4.服务端将根据文件路径打开文件进行分段发送
5.客户端也根据服务端发送的文件消息头新建一个同样类型的文件名,进行写操作

当未选择要下载的文件时,也会给出提示“请选择您要下载的文件”。

如果自己对现在的背景不满意,也可以点击修改背景,换为自己喜欢的图片。
最后就是点击退出操作。

主界面:

import os
import cv2
import Client
import Server
import socket
import tkinter
import threading
from tkinter import ttk
from PIL import Image,ImageTk
from tkinter import filedialog
from tkinter.messagebox import showerror,showinfo,showwarningroot=tkinter.Tk()
#设置主窗口标题
root.title('文件传输——Keep_Trying_Go')
#设置主窗口大小
root['width']=800
root['height']=600
#固定窗口大小
root.resizable(0,0)
#设置主窗口背景颜色
root['background']='#FFFFFF'
#设置主窗口图标
#设置标题为图像形式,第一个参数设置为True,表示该图标适用于所有的窗口
#这里注意图像格式为.png,就算是从.jpg到.png的格式转换也不能,只能是.png格式
root.iconphoto(True,tkinter.PhotoImage(file='title.png'))#背景图自适应大小
def ChangeBackground(w,h,w_box,h_box,PIL_Image):""":param w: 图片的宽度:param h: 图片的高度:param w_box: 画布的宽度:param h_box: 画布的高度:param PIL_Image::return:"""factor_w=1.0*w_box/wfactor_h=1.0*h_box/hfactor=min([factor_h,factor_w])#新的图片高度和宽度width=int(w*factor)height=int(h*factor)print('width: {}'.format(width))print('height: {}'.format(height))return PIL_Image.resize((width,height),Image.ANTIALIAS)tk_image_file=''
def setBackground(root,filename):""":param root: 主窗口:return:"""global tk_image_filePIL_Image=Image.open(filename)w,h=PIL_Image.sizePIL_Image_Size=ChangeBackground(w,h,600,450,PIL_Image)# PIL.ImageShow.show(PIL_Image_Size)try:#方式一#创建画布canvas=tkinter.Canvas(root,bg='white',width=598,height=450,borderwidth=1)canvas.place(x=5,y=0)#加在图片文件tk_image_file=ImageTk.PhotoImage(PIL_Image_Size)#将图片放置在创建的画布上image=canvas.create_image(0,0,anchor='nw',image=tk_image_file)# #将图像放置画布上端,也就是主窗口‘前方’# canvas.pack(side='top')#方法二# label=tkinter.Label(root,image=tk_image_file,width=600,height=450)# label.place(x=90,y=0)except :print('加载图像出错')def SelectBackground(root):""":param root::return:"""filename=filedialog.askopenfilename(title='选择传输文件')if not filename:showinfo(title='提示',message='未选择传输文件')# 如果没有选择采用默认filename='Background.png'setBackground(root,filename)
btn_cov=tkinter.Button(root,text='修改背景',font=('黑体',14),width=17,height=1,cursor='hand2',command=lambda :SelectBackground(root),bg='#00FF7F')
btn_cov.place(x=615,y=350)def CloseEvent(root):""":param root::return:"""btn_close=tkinter.Button(root,text='退出',font=('黑体',14),width=17,height=1,cursor='hand2',command=root.destroy,background='#708090')btn_close.place(x=615,y=400)def SelectFile(root):""":param root::return:"""filename=filedialog.askopenfilename(title='选择传输文件')if not filename:showinfo(title='提示',message='请选择发送文件')# 如果没有选择采用默认filename='File/hometown.jpg'socket_Client=Client.socket_client()threading_client=threading.Thread(target=Client.Client_Send_File,args=(socket_Client,filename,root))threading_client.start()btn_client=tkinter.Button(root,text='选择发送文件',font=('黑体',14),width=17,height=1,cursor='hand2',bg='#00FF7F',command=lambda :SelectFile(root))
btn_client.place(x=615,y=90)def SwitchServer(root):""":param root::return:"""threading_server=threading.Thread(target=Server.Server_Recv_File)threading_server.start()btn_client=tkinter.Button(root,text='开启发送文件服务端',font=('黑体',14),width=17,height=1,cursor='hand2',bg='#00FF7F',command=lambda :SwitchServer(root))
btn_client.place(x=615,y=140)def SelectdownloadFile(root):""":param root::return:"""filename=filedialog.askopenfilename(title='选择下载文件')if not filename:showinfo(title='提示',message='请选择您要下载的文件')#如果没有选择采用默认filename='File/hometown.jpg'socket_Client=Client.socket_client()threading_client=threading.Thread(target=Client.Download_Server,args=(socket_Client,filename,root))threading_client.start()btn_client_down=tkinter.Button(root,text='选择下载文件',font=('黑体',14),width=17,height=1,cursor='hand2',bg='#00FF7F',command=lambda :SelectdownloadFile(root))
btn_client_down.place(x=615,y=210)def SwitchdownloadServer(root):""":param root::return:"""threading_server=threading.Thread(target=Server.server_Send_File)threading_server.start()btn_server_send=tkinter.Button(root,text='开启下载文件服务端',font=('黑体',14),width=17,height=1,cursor='hand2',bg='#00FF7F',command=lambda :SwitchdownloadServer(root))
btn_server_send.place(x=615,y=260)if __name__=='__main__':print('PyCharm')setBackground(root, filename='Background.png')CloseEvent(root)root.mainloop()

客户端代码:

import os
import tkinterimport cv2
import json
import socket
import threading
from tkinter import ttk
#读取文件的最大数
max_len=1024def socket_client():#端口号和IP地址remote_PORT=5555remote_IP=socket.gethostbyname(socket.gethostname())remote_addr=(remote_IP,remote_PORT)#绑定端口号和IP地址socket_Client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)socket_Client.connect(remote_addr)return socket_Clientdef ProgressBar(root,text):label=tkinter.Label(root,text=text,font=('黑体',14))label.place(x=100,y=500)progressbar=ttk.Progressbar(root)progressbar.place(x=200,y=500)#设置进度条的最大值progressbar['maximum']=100#设置进度条的长度progressbar['length']=280#初始化初值progressbar['value']=0return progressbardef Client_Send_File(socket_Client,filepath,root):""":param socket: 客户端套接字:param filename: 要传输的文件:param root:主窗口:return:"""progressbar=ProgressBar(root,'发送进度')#分离路径和文件名path, filename = os.path.split(filepath)print('path: {}'.format(path))print('filename: {}'.format(filename))#分离文件名和文件后缀file, class_file = os.path.splitext(filename)#首先将消息头发送至服务端#获取文件大小# file_size=os.path.getsize(filename)file_Size=os.stat(filepath).st_sizemsg_header={'filename':file,'msg_type':class_file,'msg_len':file_Size}msg_header_bytes=bytes(json.dumps(msg_header),encoding='utf-8')#当消息头的长度不满1024时,使用空格填充msg_header_bytes+=b''*(max_len-len(msg_header_bytes))socket_Client.send(msg_header_bytes)file_len=0recv_count=0#发送的文件头大小print('msg_header_bytes: {}'.format(len(msg_header_bytes)))#发送的文件大小print('file_size: {}'.format(file_Size))with open(filepath,'rb') as fp:while file_len!=file_Size:message=fp.read(max_len)socket_Client.send(message)file_len+=len(message)progressbar['value']=file_len/file_Size*100recv_count+=1print('发送次数: {}'.format(recv_count))socket_Client.close()print('发送完成...')#客户端从服务端下载文件
def Download_Server(socket_Client,filepath,root):""":param socket_Client: 客户端套接字:param filepath: 文件路径:param root: 主窗口:return:"""progressbar=ProgressBar(root,'下载进度')socket_Client.send(filepath.encode('utf-8'))# 获取客户端发送的消息头msg_header = socket_Client.recv(max_len)header = json.loads(msg_header.decode('utf-8'))# 输出客户端发送的消息头信息print(header)# 保存接收文件的地方curr_path = os.getcwd()filename = curr_path + '\\client_recv_File\\client_recv_' + header['filename'] + header['msg_type']get_file_Size = header['msg_len']file_size = 0# 输出文件名和文件大小print('文件名: {}'.format(filename))print('file_size: {}'.format(get_file_Size))recv_count = 0# 如果文件不存在则创建if os.path.exists(filename) == False:with open(filename, 'wb') as fp:while file_size != get_file_Size:message = socket_Client.recv(max_len)fp.write(message)file_size += len(message)progressbar['value']=file_size/get_file_Size*100recv_count += 1else:with open(filename, 'wb') as fp:while file_size != get_file_Size:message = socket_Client.recv(max_len)fp.write(message)file_size += len(message)progressbar['value'] = file_size / get_file_Size * 100recv_count += 1print('接收次数: {}'.format(recv_count))socket_Client.close()print('下载完成...')if __name__=='__main__':print('Pycharm')socket_Client=socket_client()Client_Send_File(socket_Client,'File\\2014.rar')

服务端代码:

import cv2
import os
import json
import socket
import threading
#读取文件的最大数
max_len=1024def socket_server():# 端口号和IP地址remote_PORT = 5555remote_IP = socket.gethostbyname(socket.gethostname())remote_addr = (remote_IP, remote_PORT)# 绑定IP地址和端口号PORTsocket_Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)socket_Server.bind(remote_addr)# 监听socket_Server.listen()print('正在监听来自客户端的消息......')return socket_Serverdef Server_Recv_File():""":param socket: 服务端套接字:param root: 主窗口:return:"""socket_Server=socket_server()new_socket, addr = socket_Server.accept()#获取客户端发送的消息头msg_header=new_socket.recv(max_len)header=json.loads(msg_header.decode('utf-8'))#输出客户端发送的消息头信息print(header)#保存接收文件的地方curr_path=os.getcwd()filename=curr_path+'\\server_recv_File\\server_recv_'+header['filename']+header['msg_type']get_file_Size=header['msg_len']file_size=0#输出文件名和文件大小print('文件名: {}'.format(filename))print('file_size: {}'.format(get_file_Size))recv_count=0#如果文件不存在则创建if os.path.exists(filename)==False:with open(filename,'wb') as fp:while file_size!=get_file_Size:message=new_socket.recv(max_len)fp.write(message)file_size+=len(message)recv_count+=1else:with open(filename,'wb') as fp:while file_size!=get_file_Size:message=new_socket.recv(max_len)fp.write(message)file_size+=len(message)recv_count+=1print('接收次数: {}'.format(recv_count))new_socket.close()print('发送完成...')#服务端接收客户端的下载文件请求,并进行发送
def server_Send_File():""":param new_socket::return:"""socket_Server = socket_server()new_socket, addr = socket_Server.accept()filepath=new_socket.recv(max_len).decode('utf-8')print('filepath: {}'.format(filepath))# 分离路径和文件名path, filename = os.path.split(filepath)print('path: {}'.format(path))print('filename: {}'.format(filename))# 分离文件名和文件后缀file, class_file = os.path.splitext(filename)# 首先将消息头发送至服务端# 获取文件大小# file_size=os.path.getsize(filename)file_Size = os.stat(filepath).st_sizemsg_header = {'filename': file, 'msg_type': class_file, 'msg_len': file_Size}msg_header_bytes = bytes(json.dumps(msg_header), encoding='utf-8')# 当消息头的长度不满1024时,使用空格填充msg_header_bytes += b'' * (max_len - len(msg_header_bytes))new_socket.send(msg_header_bytes)file_len = 0recv_count = 0# 发送的文件头大小print('msg_header_bytes: {}'.format(len(msg_header_bytes)))# 发送的文件大小print('file_size: {}'.format(file_Size))with open(filepath, 'rb') as fp:while file_len != file_Size:message = fp.read(max_len)new_socket.send(message)file_len += len(message)recv_count += 1print('发送次数: {}'.format(recv_count))new_socket.close()print('发送完成...')if __name__=='__main__':print('Pycharm')Server_Recv_File()

python中使用socket编程实现带有界面的客户端向服务端发送文件和下载文件相关推荐

  1. gRPC中Java和node进行异构通信-互为客户端和服务端

    场景 gPRC简介以及Java中使用gPRC实现客户端与服务端通信(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/ ...

  2. java网络编程Socket实现客户端向服务端发送信息

    (可按目录按需阅读,我一般会整理的比较细) 前置知识 java IO Socket 什么是socket?socket字面意思其实就是一个插口或者套接字,包含了源ip地址.源端口.目的ip地址和源端口. ...

  3. Java线程怎么发送消息_Java客户端Socket如何能在阻塞线程下收到服务端发送来的消息?...

    最近在写Socket客户端的时候遇到点问题 客户端在创建时创建了2个线程 一个监听键盘输入事件,使用的是buffered,当检测到输入完成时写入流发送给服务端. String content = &q ...

  4. python中使用socket编程实现图片或者其他文件的传输

    客户端: import os import cv2 import json import socket import threading #读取文件的最大数 max_len=1024#端口号和IP地址 ...

  5. C++socket编程(三):3.6 服务端recv客户端发送的数据

    服务端中获取客户端发送过来的数据一定是关闭套接字之前进行,close之后就收不到数据了. 一般读取数据一般用read,windows上一般用recv(本质上也是read),但是为了跨平台,所以一般用r ...

  6. gPRC简介以及Java中使用gPRC实现客户端与服务端通信(附代码下载)

    场景 ProtoBuf的介绍以及在Java中使用protobuf将对象进行序列化与反序列化: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/det ...

  7. flask和socket结合使用实现客户端向服务端发送文件

    文章目录 1.实验效果 2.文件结构说明 3.操作步骤 4.代码下载 5.服务端文件 6.客户端文件 7.前端文件 1.实验效果 成功发送文件和接收文件 2.文件结构说明 3.操作步骤 (1)首先运行 ...

  8. C++socket编程(三):3.7 服务端回应send客户端数据

    为什么提到反馈send客户端数据,是因为本章博客,目前为止都是单线程的.我们一个服务端只能接收第一个连接进行的客户端发送的数据,在这个客户端断开连接之前,我们的服务端都无法接收其他客户端发过来的数据了 ...

  9. linux网络编程之用多线程实现客户端到服务端的通信(基于udp)

    1.开启一个线程接受数据,主线程发送数据的代码 #include <unistd.h> #include <stdio.h> #include <stdlib.h> ...

最新文章

  1. 使用slice和concat对数组的深拷贝和浅拷贝
  2. 请问生产成本收集器与标准成本评估有什么关联?
  3. stanford-parser for C#
  4. 【MyBiatis框架】原生态Jdbc的弊端已经Mybatis简介
  5. 腾讯获准在中国销售Switch游戏机 任天堂股价应声飙升逾14%
  6. 交换机虚拟化和堆叠的区别_交换机级联与堆叠有何区别
  7. Python+selenium+eclipse执行web自动化(四)控件处理
  8. expect自动登录以及远程脚本执行
  9. Topcoder的使用方法
  10. TwinCAT3中台达A2增量编码器伺服使用PDO方式回零
  11. 机器学习导论(五)-神经元网络
  12. python文件数据类型_Python核心数据类型-文件
  13. 大学生阅读小说网页设计模板代码 小说书籍网页作业成品 学校书籍网页制作模板 学生简单书籍阅读网站设计成品
  14. 韦东山C语言加强07
  15. 多旅行商问题——公式和求解过程概述
  16. 917. 仅仅反转字母
  17. React性能优化SCU | PureComponent | memo
  18. 「WAVE SUMMIT 2022深度学习开发者峰会」火热来袭
  19. 尚硅谷大数据视频_Shell视频教程
  20. loadimage 在picture控件上加载位图失败

热门文章

  1. Gerapy分布式管理框架
  2. themleaf返回可以带目录结构
  3. 亲测可以使用的:Maven将中央仓库修改为阿里云的maven仓库
  4. 基于交换技术的网络中,全双工主要运行在?( 内有答案与详解)
  5. Linux7 CENTOS7修改root密码
  6. 3D 视觉 相关知识-SLAM框架-常见方案对比
  7. 06 回归算法 - 损失函数、过拟合欠拟合
  8. Apache 基金会发布2018财年年报:Java 项目占大半
  9. Activit流程部署、删除
  10. Java 分页之最简单的算法