客户端代码:
#!/usr/bin/python3.5
__auth__ = 'WuYongQi'
import socket,pickle,os,sys
def up_duandian(obj,filename):
duandian = str(obj.recv(1024),encoding='utf-8')
if duandian == 'No':
print('文件不存在!')
else:
duandian = int(duandian)
print(duandian)
obj.sendall(bytes(str(os.stat(filename).st_size),encoding='utf-8'))
f = open(filename,'rb')
f.seek(duandian)
j = '※'
biaoshi = duandian/os.stat(filename).st_size*100
for i in f:
duandian += len(i)
if biaoshi <= duandian/os.stat(filename).st_size*100:
biaoshi += 1
j = j+'※'
sys.stdout.write(str(float(duandian/os.stat(filename).st_size*100))+'%\t |'+j+"\r")
sys.stdout.flush()
obj.sendall(i)
return '发送完成'
def down_duandian(obj,filename):
if str(obj.recv(1024),encoding='utf-8') == 'No':
print('服务器端文件不存在!')
else:
f1 = open(filename,'rb')
f1.read()
weizhi = str(f1.tell())
f1.close()
print(weizhi)
obj.sendall(bytes(weizhi,encoding='utf-8'))
weizhi = int(weizhi)
file_size = int(obj.recv(1024))
f = open(filename,'r+b')
j = '※'
biaoshi = weizhi/file_size*100
while True:
if file_size == weizhi:
break
data = obj.recv(1024)
f.write(data)
weizhi += len(data)
if biaoshi <= weizhi/file_size*100:
biaoshi += 1
j = j+'※'
sys.stdout.write(str(float(weizhi/file_size*100))+'%\t |'+j+"\r")
sys.stdout.flush()
return '接收完成!'
def user_ftp(obj):
print(str(obj.recv(1024),encoding='utf-8'))
user_in_ftp = input('>>>')
if user_in_ftp == 'q':
obj.sendall(bytes(user_in_ftp,encoding='utf-8'))
return False
obj.sendall(bytes(user_in_ftp,encoding='utf-8'))
if user_in_ftp == '1':
file_name = input('请输入上传后文件名称:')
server = str(obj.recv(1024),encoding='utf-8')
obj.sendall(bytes(file_name,encoding='utf-8'))
if server == 'uploading':
return ftp_server(obj)
server = str(obj.recv(1024),encoding='utf-8')
if server == 'downloading':
return ftp_client(obj)
def ftp_server(obj):
user_up_ftp = input('请输入要上传的文件路径\n>>>')
file_size = os.stat(user_up_ftp).st_size#查看文件大小
file_finish = 0 #文件已上传大小已完成
obj.sendall(bytes(str(file_size),encoding='utf-8'))#要上传的文件大小传给服务端
obj.recv(1024)#接收一次服务端的信息,以防止粘包
f = open(user_up_ftp,'rb')
j = '※'
biaoshi = 1
for i in f:
file_finish += len(i)
if biaoshi <= file_finish/file_size*100:
biaoshi += 1
j = j+'※'
sys.stdout.write(str(float(file_finish/file_size*100))+'%\t |'+j+"\r")
sys.stdout.flush()
obj.sendall(i)
return '发送完成'
def ftp_client(obj):
ser_name = input('请输入服务器上的文件名:')
obj.sendall(bytes(ser_name,encoding='utf-8'))
filename = input('请输入下载后的名称:')
file_size = str(obj.recv(1024),encoding='utf-8')#要上传文件的大小
if file_size == 'No':
return '文件不存在!'
file_size = int(str(obj.recv(1024),encoding='utf-8'))
obj.sendall(bytes('OK',encoding='utf-8'))#给客户端发一个消息,防止粘包
f = open(filename,'wb')
file_finish = 0
j = '※'
biaoshi = 1
while True:
try:
if file_size == file_finish:
break
data = obj.recv(1024)
file_finish += len(data)
if biaoshi <= file_finish/file_size*100:
biaoshi += 1
j = j+'※'
sys.stdout.write(str(float(file_finish/file_size*100))+'%\t |'+j+"\r")
sys.stdout.flush()
f.write(data)
except KeyboardInterrupt:
print('客户端强制退出!')
break
return '接收完成!'
obj = socket.socket()
obj.connect(('127.0.0.1',8080))
data1 = pickle.loads(obj.recv(1024))
for i,k in enumerate(data1,1):
print(i,k)
while True:
biaoshi = 0
data12 = str(obj.recv(1024),encoding='utf-8')
if data12 == 'ftp':
obj.sendall(bytes('OK',encoding='utf-8'))
user_in = user_ftp(obj)
if user_in:
print(str(obj.recv(1024),encoding='utf-8'))
continue
else:
obj.sendall(bytes('q',encoding='utf-8'))
break
elif data12 == 'command':
usr_command = input('请输入要执行的命令 >>>>')
obj.sendall(bytes(usr_command,encoding='utf-8'))
comm_size = str(obj.recv(1024),encoding='utf-8')
print(comm_size)
obj.sendall(bytes('OK',encoding='utf-8'))
if comm_size.isdigit():
comm_size = int(comm_size)
text = ''
for i in range(1,comm_size):
try:
data = obj.recv(1024)
print(str(data,encoding='utf-8'))
text = '%s%s'%(text,str(data,encoding='utf-8'))
except Exception:
print('强制退出!')
break
# while True:
# try:
# if comm_size <= 0:
# print(comm_size,1111111111111111111)
# break
# print(comm_size,'9999999999999')
# data = obj.recv(1024)
# text = '%s%s'%(text,data)
# print(str(data,encoding='utf-8'))
# comm_size -= len(bytes(data))
# except KeyboardInterrupt:
# print('强制退出!')
# break
print(str(text),'123123123123123123123123123123123123123123')
print(str(obj.recv(1024), encoding='utf-8'))
obj.sendall(bytes('OK',encoding='utf-8'))
continue
else:
command_result = pickle.loads(obj.recv(1024))
print(str(command_result, encoding='utf-8'))
print(str(obj.recv(1024), encoding='utf-8'))
continue
elif data12 == 'duandian':
user_xuanze = input('请输入断点续传操作:\n'
'1、上传文件\n'
'2、下载文件')
obj.sendall(bytes(user_xuanze,encoding='utf-8'))
obj.recv(1024)
if user_xuanze == '1':
file_up = input('请输入上传文件名:')
file_up2 = input('请输入上传的本地文件路径:')
obj.sendall(bytes(file_up,encoding='utf-8'))
up_duandian(obj,file_up2)
continue
elif user_xuanze == '2':
file_down = input('请输入下载的服务器端的文件名:')
file_down2 = input('请输入下载的本地文件路径:')
obj.sendall(bytes(file_down,encoding='utf-8'))
down_duandian(obj,file_down2)
continue
else:
print('输入错误!')
continue
else:
inp = input(data12)
if inp.isdigit():
if int(inp) >= len(data1) or int(inp) >= 1:
obj.sendall(bytes(str(int(inp)-1), encoding='utf-8'))
else:
print('输入的值有误,请从新输入')
elif biaoshi == 0:
if inp == 'q':
obj.sendall(bytes(inp,encoding='utf-8'))
break
else:
biaoshi += 1
obj.sendall(bytes(inp,encoding='utf-8'))
else:
obj.sendall(bytes(inp,encoding='utf-8'))
View Code
服务端格式:
- sock_server:
- bin:
- server.py
#!/usr/bin/python3.5
__auth__ = 'WuYongQi'
import socket,socketserver,pickle,os,sys
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__)),'config'))
import class_user,hashlib,sys_config
username = ''
def login(conn):
hash = hashlib.sha512()
conn.sendall(bytes('请输入用户名', encoding='utf-8'))
global username
username = str(conn.recv(1024), encoding='utf-8')
conn.sendall(bytes('请输入密码', encoding='utf-8'))
hash.update(conn.recv(1024))
urpd = class_user.user(username, hash.hexdigest()).login()
if urpd:
conn.sendall(bytes('登陆成功!(按回车继续)', encoding='utf-8'))
else:
conn.sendall(bytes('账号密码有误!(按回车继续)', encoding='utf-8'))
login(conn)
def register(conn):
hash = hashlib.sha512()
conn.sendall(bytes('请输入用户名', encoding='utf-8'))
username = str(conn.recv(1024), encoding='utf-8')
urdp = class_user.user(username).register()
if not urdp:
conn.sendall(bytes('用户名重复,请重新输入!(按回车继续)',encoding='utf-8'))
register(conn)
while True:
conn.sendall(bytes('请输入密码', encoding='utf-8'))
pwd1 = conn.recv(1024)
conn.sendall(bytes('请确认密码', encoding='utf-8'))
pwd2 = conn.recv(1024)
if pwd1== pwd2:
hash.update(pwd2)
urpd = class_user.user(username, hash.hexdigest()).register()
if urdp:
conn.sendall(bytes('注册成功!(按回车继续)', encoding='utf-8'))
break
else:
conn.sendall(bytes('注册失败!(按回车继续)', encoding='utf-8'))
register(conn)
else:
conn.sendall(bytes('密码确认失败!(按回车继续)',encoding='utf-8'))
continue
def command(conn):
import subprocess
conn.sendall(bytes('command',encoding='utf-8'))
command = str(conn.recv(1024),encoding='utf-8')
try:
a = subprocess.check_output(command,shell=True)
except Exception:
return '命令有误!(按回车继续)'
if len(a) >= 1024 :
file_size = len(a) # 查看大小
print(file_size,'kjghjdgj')
conn.sendall(bytes(str(file_size), encoding='utf-8')) # 要上传的文件大小传给服务端
conn.recv(1024) # 接收一次客户端的信息,以防止粘包
print(str(a,encoding='gbk'))
for i in str(a,encoding='utf-8'):
conn.sendall(bytes(str(i),encoding='utf-8'))
return '发送完成'
else:
conn.sendall(pickle.dumps(a))
return '执行完毕'
def duandianxuchuan(conn):
conn.sendall(bytes('duandian',encoding='utf-8'))
xuanze = str(conn.recv(1024),encoding='utf-8')
if xuanze == '1':
conn.sendall(bytes('文件名',encoding='utf-8'))
filename = str(conn.recv(1024),encoding='utf-8')
return up_file(conn,filename)
elif xuanze == '2':
conn.sendall(bytes('文件名',encoding='utf-8'))
filename = str(conn.recv(1024),encoding='utf-8')
return down_file(conn,filename)
def up_file(conn,filename):
if os.path.exists(os.path.join(sys_config.USER_DB,'home',username,filename)):
f1 = open(os.path.join(sys_config.USER_DB,'home',username,filename),'r+b')
f1.read()
weizhi = f1.tell()
conn.sendall(bytes(str(weizhi),encoding='utf-8'))
print(weizhi)
file_size = int(str(conn.recv(1024),encoding='utf-8')) - weizhi
print(file_size)
while True:
try:
print(file_size)
if file_size == 0:
break
data = conn.recv(1024)
f1.write(data)
file_size -= len(data)
except KeyboardInterrupt:
print('客户端强制退出!')
break
f1.close()
print('完成')
return '接收完成!(按回车继续)'
else:
print('文件不存在!(按回车继续)')
return 'No'
def down_file(conn,filename):
if not os.path.exists(os.path.join(sys_config.USER_DB,'home',username,filename)):
print('文件不存在!(按回车继续)')
return 'No'
else:
conn.sendall(bytes('kong',encoding='utf-8'))
duandian = int(conn.recv(1024))
print(type(duandian))
print(os.stat(os.path.join(sys_config.USER_DB,'home',username,filename)).st_size)
conn.sendall(bytes(str(os.stat(os.path.join(sys_config.USER_DB,'home',username,filename)).st_size),encoding='utf-8'))
f = open(os.path.join(sys_config.USER_DB,'home',username,filename),'r+b')
f.seek(duandian)
for i in f:
conn.sendall(i)
f.close()
return '发送完成!(按回车继续)'
def ftpserver(conn):
conn.sendall(bytes('ftp',encoding='utf-8'))
conn.recv(1024)
conn.sendall(bytes('1、上传文件\n2、下载文件\nq、退出系统', encoding='utf-8'))
user_ftp = str(conn.recv(1024),encoding='utf-8')
if user_ftp == '1':
conn.sendall(bytes('uploading',encoding='utf-8'))#请输入上传后的文件名称:
file_name = str(conn.recv(1024),encoding='utf-8')
return uploading(conn,file_name)
elif user_ftp == '2':
conn.sendall(bytes('downloading',encoding='utf-8'))#请输入要下载的文件名称:
file_name = str(conn.recv(1024),encoding='utf-8')
return downloading(conn,file_name)
elif user_ftp == 'q':
return None
def uploading(conn,filename):
print(os.path.join(sys_config.USER_DB,'home',username,filename))
file_size = int(str(conn.recv(1024),encoding='utf-8'))#要上传文件的大小
conn.sendall(bytes('OK',encoding='utf-8'))#给客户端发一个消息,防止粘包
f = open(os.path.join(sys_config.USER_DB,'home',username,filename),'wb')
while True:
try:
if file_size == 0:
break
data = conn.recv(1024)
f.write(data)
file_size -= len(data)
except KeyboardInterrupt:
print('客户端强制退出!')
break
return '接收完成!'
def downloading(conn,filename):
user_up_ftp = filename
print(user_up_ftp)
if os.path.exists(os.path.join(sys_config.USER_DB,'home',username,user_up_ftp)):
file_size = os.stat(user_up_ftp).st_size#查看文件大小
conn.sendall(bytes(str(file_size),encoding='utf-8'))#要上传的文件大小传给服务端
conn.recv(1024)#接收一次客户端的信息,以防止粘包
f = open(user_up_ftp,'rb')
for i in f:
conn.sendall(i)
return '发送完成'
else:
return 'No'
class server_much(socketserver.BaseRequestHandler):
def handle(self):
print('asdkvjhalskjbvjkasbldvrawe')
conn = self.request
print('客户端ip:',self.client_address[0],'\n客户端端口:',self.client_address[1])
index = ['登陆', '注册']
conn.sendall(pickle.dumps(index))
conn.sendall(bytes('请输入接下来的操作,按Q退出!',encoding='utf-8'))
# while True:
data1 = conn.recv(1024)
if str(data1,encoding='utf-8') == 'q':
conn.close()
# break
if data1.strip().isdigit():
if index[int(data1)] == '登陆':
login(conn)
while True:
user_inp = '1、ftp\n2、command\n3、断点续传\n任意字符串退出系统\n>>>>>'
conn.sendall(bytes(user_inp,encoding='utf-8'))
user_in = str(conn.recv(1024),encoding='utf-8')
if user_in.isdigit():
if user_in == '0':
ret = ftpserver(conn)
conn.sendall(bytes(ret,encoding='utf-8'))
conn.sendall(bytes(user_inp,encoding='utf-8'))
continue
elif user_in == '1':
ret = command(conn)
conn.sendall(bytes(ret,encoding='utf-8'))
continue
elif user_in == '2':
ret = duandianxuchuan(conn)
conn.sendall(bytes(ret,encoding='utf-8'))
continue
else:
conn.close()
break
elif index[int(data1)] == '注册':
register(conn)
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),server_much)
server.serve_forever()
- View Code
- config:
- class_user.py
#!/usr/bin/python3.5
__auth__ = 'WuYongQi'
import pickle,hashlib,os,sys
CONFIG = os.path.join(os.path.dirname(os.path.dirname(__file__)),'config')
USER_DB = os.path.join(os.path.dirname(os.path.dirname(__file__)),'user_db')
class user:
def __init__(self,username,password=0):
self.username = username
self.password = password
def login(self):
a = open(USER_DB+'/db','r', encoding='utf-8') # 获取数据
for i in a: # 循环获取数据的每一行
i = i.strip() # 去掉两边的空格或其他字符串
i = i.split('#') # 以#号分割
if self.username == i[0] and self.password == i[1]: # 判断用户输入的账号密码是用索引去对应的位置是否一样
print('登陆成功') # 返回值
return True
return False # 返回值
def register(self):
with open(USER_DB+'/db', 'r+', encoding='utf-8') as f: # 去读现在又的账号密码
for i in f: # 循环获取数据的每一行
i = i.strip() # 去掉两边的空格或其他字符串
i = i.split('#') # 以#号分割
if self.username == i[0]: # 判断用户输入的账号是否存在
return False # 存在输出并重新执行
if self.password == 0:
return 'N'
f.write('\n' + self.username + '#' + self.password) # 成功创建用户,并一#号分割账号密码
return '注册成功' # 返回注册成功
- View Code
- sys_config.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
__author__ = 'WuYongQi'
import os
CONFIG = os.path.join(os.path.dirname(os.path.dirname(__file__)),'config')
USER_DB = os.path.join(os.path.dirname(os.path.dirname(__file__)),'user_db')
- View Code
- user_db:
- home
- wuqi
- 存放用户文件
- db#用户登录账号密码:
wu#933ec0a594667c5f77870cfccfd7a1d66e2b7cd74e685b1bbfbd07a07690e6d421c835ea0522c1308d95866c7b728996083b678350900dfa8c5c4393462c5d5d
admin#e54a9de41b39d03910cd04cd713612b10906a45d54cc158f042711629ef15e0e07eaa71958c8f1404a899bed3036a462f650116b28265822948a2cf25783b20b
alex#e7205add494f33c5ebe8bda3a41c2c1a3e1152733ce7988d7de7190b076976d718a4e8bd3b5dc3211c810a57ca89a68eff74d55ab9b3ea7f3b5488f53e177888
wuqi#e0de6b065348b12c68f663b7b965fa3e87101409668a7a9948e28ebefc1ab87ea21800012a49ae4d9cca94ac2ec94fa0e075978deaf8f9c2c4763a645e294f78
- View Code