一主界面: **二:发送文件界面:**首先需要开启发送文件服务端(这里需要注意的是每一次发送文件之前都需要开启一次服务端,因为我在这里将每一次发送文件之后就关闭了客户端和服务端之间的连接) 输出相关客户端和服务端的文件传输过程中的信息: 如果发送文件没有选择,将会得到提示“请选择发送文件” 三:下载文件主界面:首先需要开启下载文件服务端(同样,这里需要注意的是每一次发送文件之前都需要开启一次服务端,因为我在这里将每一次发送文件之后就关闭了客户端和服务端之间的连接) 注意:这里的下载文件的思路: 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,showwarning
root=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/w
factor_h=1.0*h_box/h
factor=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_file
PIL_Image=Image.open(filename)
w,h=PIL_Image.size
PIL_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 tkinter
import cv2
import json
import socket
import threading
from tkinter import ttk
#读取文件的最大数
max_len=1024
def socket_client():
#端口号和IP地址
remote_PORT=5555
remote_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_Client
def 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']=0
return progressbar
def 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_size
msg_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=0
recv_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*100
recv_count+=1
print('发送次数: {}'.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*100
recv_count += 1
else:
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 * 100
recv_count += 1
print('接收次数: {}'.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=1024
def socket_server():
# 端口号和IP地址
remote_PORT = 5555
remote_IP = socket.gethostbyname(socket.gethostname())
remote_addr = (remote_IP, remote_PORT)
# 绑定IP地址和端口号PORT
socket_Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_Server.bind(remote_addr)
# 监听
socket_Server.listen()
print('正在监听来自客户端的消息......')
return socket_Server
def 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+=1
else:
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+=1
print('接收次数: {}'.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_size
msg_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 = 0
recv_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 += 1
print('发送次数: {}'.format(recv_count))
new_socket.close()
print('发送完成...')
if __name__=='__main__':
print('Pycharm')
Server_Recv_File()
|