服务端代码:
import json
import socket
import hashlib
import subprocess
import os
def file_md5(file_names): #计算文件的MD5值,进行检验
f = open(file_names,“rb”)
f_contents = f.read()
file_md5_sum = hashlib.md5(f_contents).hexdigest()
f.close()
return file_md5_sum
def progress_bar(total_size): #文件传输进度条显示的生成器
receive_percent = 0
while receive_percent <= 100:
recv_size = yield
new_percent = int((recv_size/int(total_size))*100)
if new_percent >= receive_percent:
print(f"\r{’>’ * new_percent}{new_percent}%", end="", flush=True)
receive_percent = new_percent
def login(account):
while True:
if user.user_name == account[0] and user.user_password == account[1]:
login_status = 1
return login_status
else:
login_status = 0
return login_status
class User(object):
def init(self,user_name,user_password):
self.user_name = user_name
self.user_password = user_password
user = User(“alex”,“abc”) #创建一个用户
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((“localhost”,9000))
s.listen(2)
while True:
conn,addr = s.accept()
data = conn.recv(1024).decode().split() # 服务端接收账号密码
user_login_status = login(data)
if user_login_status == 1:
conn.send(f"账号密码正确,账号登录成功 {user_login_status}".encode())
while user_login_status == 1:
data_cmd = conn.recv(1024).decode().split() #接收指令
if data_cmd[0] == “get”:
file_name = data_cmd[1]
if os.path.isfile(file_name): #判断文件是否存在
file_size = os.path.getsize(file_name) #得到文件大小
file_size_head = f"|{file_size}".zfill(32)
conn.send(file_size_head.encode()) #发送文件大小的固定长度的消息头
filemd5 = file_md5(file_name).encode() #计算文件的MD5值,进行检验
conn.send(filemd5) #将文件MD5值发送
f = open(file_name,“rb”) #以二进制格式打开文件
for line in f:
conn.send(line)
f.close()
else:
conn.send(“文件不存在”.encode())
elif data_cmd[0] == “put”:
upload_file_name = data_cmd[1]
upload_head = conn.recv(32)
upload_file_size = upload_head.decode().split("|")[1]
upload_file_md5 = conn.recv(1024).decode()
f_upload = open(f"{upload_file_name}.upload",“wb”)
upload_receive_size = 0
while upload_receive_size < int(upload_file_size): # 循环接收文件数据
upload_file_data = conn.recv(1024)
upload_receive_size += len(upload_file_data)
f_upload.write(upload_file_data) # 将每次接收到的数据写入文件中
f_upload.close()
if upload_file_md5 == file_md5(f"{upload_file_name}.upload"):
conn.send(“文件校验成功,文件上传成功”.encode())
else:
conn.send(“文件校验失败,请重新上传”.encode())
else:
cmd_result = str(subprocess.getstatusoutput(data_cmd[0])[1]) #执行命令,得到结果,返回一个元组格式,强制字符串格式
cmd_result_size = str(len(cmd_result)) #计算该命令结果的大小
cmd_result_head = f"|{cmd_result_size}".zfill(32)
conn.send(cmd_result_head.encode()) #将结果命令大小用32字节的长度发送过去
conn.send(cmd_result.encode())
else:
user_login_status = 0
conn.send(f"账号密码错误,请重新输入 {user_login_status}".encode())
客户端代码:
import socket
import json
import re
import os
import hashlib
import time
import os
def file_md5(file_names): #计算文件的MD5值,并返回二进制进行检验
f = open(file_names,“rb”)
f_contents = f.read()
file_md5_sum = hashlib.md5(f_contents).hexdigest()
f.close()
return file_md5_sum
def progress_bar(total_size): #文件传输进度条显示的生成器
receive_percent = 0
while receive_percent <= 100:
recv_size = yield
new_percent = int((recv_size/int(total_size))*100)
if new_percent >= receive_percent:
print(f"\r{’>’ * new_percent}{new_percent}%", end="", flush=True)
receive_percent = new_percent
while True: #登录程序
user = input(“请输入你的账号:”)
password = input(“请输入你的密码:”)
account = f"{user} {password}".encode()
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((“192.168.2.200”,9000))
client.send(account) #将账号密码传送给服务器
login_respond = client.recv(1024).decode()
print(login_respond.split()[0])
while login_respond.split()[1] == str(1): #登录成功
user_cmd = input(“请输入你想要执行的指令(系统指令/get|put filename):”).encode()
client.send(user_cmd) #发送指令
if re.match("^get",user_cmd.decode()): #正则匹配get指令,下载文件
file_name = user_cmd.decode().split()[1]
file_size_sum = client.recv(32).decode().split("|")[1] #解析得到文件大小
print(file_size_sum)
filemd5 = client.recv(1024).decode() #接收文件的校验码
f = open(f"{file_name}.download",“wb”) #创建文件
receive_file_size = 0
p = progress_bar(file_size_sum)
p.next()
while receive_file_size < int(file_size_sum): #循环接收文件数据
file_data = client.recv(1024)
receive_file_size += len(file_data)
print(receive_file_size)
f.write(file_data) #将每次接收到的数据写入文件中
p.send(receive_file_size)
f.close()
print("\n")
if filemd5 == file_md5(f"{file_name}.download"):
print(“文件校验正确,文件下载成功”)
else:
print(“文件检验失败,请重新下载”)
elif re.match("^put",user_cmd.decode()): #上传文件
upload_file_name = user_cmd.decode().split()[1]
if os.path.isfile(upload_file_name): #判断文件是否存在
upload_file_size = os.path.getsize(upload_file_name) #得到文件大小
upload_head = f"|{upload_file_size}".zfill(32)
client.send(upload_head.encode()) #发送文件大小的消息头
upload_file_md5 = file_md5(upload_file_name).encode() #计算文件的MD5值
client.send(upload_file_md5) #发送文件的MD5值
f_upload = open(upload_file_name,“rb”)
upload_file_size_part = 0
p_upload = progress_bar(upload_file_size)
p_upload.next()
for line in f_upload:
client.send(line)
upload_file_size_part += len(line)
p_upload.send(upload_file_size_part)
f_upload.close()
print("\n")
upload_file_md5_result = client.recv(1024).decode() #接收服务端对文件校验的结果
print(upload_file_md5_result)
else:
print(“文件不存在,请重新选择”)
else: #系统指令
user_cmd_result_head = client.recv(32) #接收指令结果的消息头(固定32字节)
user_cmd_result_size = user_cmd_result_head.decode().split("|")[1] #解析消息头中的长度
receive_size = 0
user_cmd_result = “”
while receive_size < int(user_cmd_result_size):
user_cmd_result_part = client.recv(1024).decode(errors=‘ignore’)
receive_size += len(user_cmd_result_part)
user_cmd_result += user_cmd_result_part
print(user_cmd_result)
接下来继续完善代码,奥里给!!!