服务端:
1 import socket 2 import socketserver 3 import struct 4 import json 5 import os 6 import time 7 import subprocess 8 9 #os.path.abspath(__file__) 显示当前文件的绝对路径 10 #os.path.dirname 显示当前文件/目录 所在的目录 11 #os.path.normpath() 规范路径,在Linux平台自动转换路径 12 13 14 flag="FBI" 15 16 class Ftp_server(socketserver.BaseRequestHandler): 17 code="utf-8" 18 def handle(self): 19 while True: 20 pwd=os.getcwd() 21 os.chdir(pwd) 22 23 recv_head_len=struct.unpack("i",self.request.recv(4))[0] #接收 客户端发来固定的报头长度数字(字节格式) 24 recv_head_data=json.loads(self.request.recv(recv_head_len)) #接收报头信息 (字典类型) 25 #根据客户端发来的报头,执行响应的方法,fla=FBI登录 26 if recv_head_data.get("flag")==flag:# print(recv_head_data) # d1 = {"name": name, "pwd": pwd,"cmd":cmd,"flag":flag} 27 self.login(recv_head_data) 28 print(recv_head_data) 29 if hasattr(self,recv_head_data["cmd"]):#其他情况 就是 put 和 get操作 30 cmd=recv_head_data["cmd"] 31 file=recv_head_data['file_name'] 32 print(cmd,file) 33 func=getattr(self,cmd) 34 func(cmd,file,recv_head_data) 35 36 37 def put(self,cmd,file,head_data): #上传 38 data_size =head_data["data_size"] 39 print(data_size) 40 res =head_data 41 42 file_path = os.path.normpath(os.path.join(r"E:\full_stack\day38" #拼接用户路径 43 'put', 44 res["name"], 45 res['pwd'])) 46 47 #姓名+密码=用户目录 48 if os.path.exists(file_path) == True: # 如果用户存在 49 os.chdir(file_path) #判断用户目录下的文件是否存在 50 os.path.exists(file) 51 if os.path.exists(file): # 如果文件存在 就代表可以断定续传,打开这个文件,先记录一下末尾的tell 52 print(file) 53 with open(file, 'rb') as f: 54 f.seek(0, 2) 55 sek = f.tell() 56 print("文件的sek%s" % sek) 57 58 if head_data["data_size"] ==sek: #如果末尾的位置 和文件的大小 相等 就代表已经存在了 无需上传 59 self.request.send(struct.pack('i',sek)) 60 print("上传的文件已经完成。") 61 62 63 else: #如果文件不完整,就代表断点续传 64 self.request.send(struct.pack('i',sek)) 65 with open(file, 'wb') as f: 66 f.seek(sek) 67 recv_size = 0 68 while recv_size < data_size: # 开写数据 69 data = self.request.recv(1024) 70 f.write(data) 71 recv_size += len(data) 72 73 74 else: # 如果文件不存在,从头开始写 75 self.request.send(struct.pack('i', 0)) 76 with open(file, 'wb') as f: 77 recv_size = 0 78 while recv_size < data_size: # 开写数据 79 data = self.request.recv(1024) 80 f.write(data) 81 recv_size += len(data) 82 self.request.send("上传完成".encode("utf-8")) 83 time.sleep(1) 84 else: #如果用户目录不存在 85 os.makedirs(file_path) 86 os.chdir(file_path) 87 self.request.send(struct.pack('i',0)) 88 with open(file, 'wb') as f: 89 recv_size = 0 90 while recv_size < data_size: # 开写数据 91 data = self.request.recv(1024) 92 f.write(data) 93 recv_size += len(data) 94 self.request.send("上传完成".encode("utf-8")) 95 time.sleep(1) 96 97 def get(self,cmd,file,head_data): #下载方法 98 filesize=os.path.getsize(file) 99 d3={"name":file,"data_size":filesize} 100 bytes_d1 = json.dumps(d3).encode("utf-8") 101 len_d1 = len(bytes_d1) 102 struct_len = struct.pack("i",len_d1) 103 self.request.send(struct_len) 104 self.request.send(bytes_d1) 105 with open(file,'rb') as f: 106 for i in f: 107 self.request.send(i) 108 else:f.close() 109 time.sleep(2) 110 self.request.send("接收完毕".encode("utf-8")) 111 112 def login(self,recv_head_data):#{'file_path': 'alex\\123', 'cmd': 'login', 'file_name': 'c'} 113 114 file_path=os.path.normpath(os.path.join(r"E:\full_stack\day38" 115 'put', 116 recv_head_data["name"], 117 recv_head_data['pwd'])) 118 os.chdir(file_path) 119 cmd = recv_head_data['cmd'] 120 print(cmd) 121 act_res = subprocess.Popen(cmd, shell=True, 122 stdout=subprocess.PIPE, 123 stdin=subprocess.PIPE, 124 stderr=subprocess.PIPE) 125 act_err = act_res.stderr.read() 126 if act_err: 127 ret = act_err 128 else: 129 ret = act_res.stdout.read() 130 bytes_len = len(ret) 131 self.request.send(struct.pack("i",bytes_len)) 132 self.request.send(ret) 133 134 135 if __name__ == '__main__': 136 obj=socketserver.ThreadingTCPServer(("127.0.0.1",8080),Ftp_server) 137 obj.serve_forever()
客户端
1 import socket 2 import struct 3 import json 4 import os 5 import mode 6 flag="FBI" 7 user_dict={"alex":'123','egon':'456'} #DB 8 9 l=["put 文件名", 'get 文件名', "login 登录" ] 10 11 #类的 __init__方法在对象实例化时自动执行,所以实例化之后对象就执行了__init__中定义的东西 12 class Client(): 13 def __init__(self,Addr_server): 14 self.addr_server=Addr_server 15 self.socket = socket.socket() 16 self.client_connect() 17 18 def client_connect(self): 19 self.socket.connect(self.addr_server) 20 21 def run(self): 22 while True: 23 name_inpu = input("请输入用户名: ") 24 psw_inpu = input("请输入密码:").strip() 25 if user_dict.get(name_inpu) == psw_inpu: 26 for i in l: 27 print(i.center(50)) 28 else: 29 print("用户名或者密码错误!".center(50)) 30 continue 31 32 flie_inpu = input("请输入FTP操作: ").strip() 33 if flie_inpu=="login": 34 self.login(name_inpu,psw_inpu) 35 else: 36 cmd, file = flie_inpu.split() 37 print(cmd,file) 38 if hasattr(mode, cmd): # 根据不同的请求,设置不同的报头的格式。 39 func = getattr(mode, cmd) 40 struct_len,bytes_d1,d1 = func(name_inpu,psw_inpu,cmd,file) 41 else: 42 continue 43 self.socket.send(struct_len) # 44 self.socket.send(bytes_d1) 45 if hasattr(self, cmd): #根据不同的报头格式,执行不同的方法 46 func = getattr(self, cmd) 47 func(d1) 48 else: 49 continue 50 51 def get(self,d1): #下载操作 52 server_head_len=struct.unpack("i",self.socket.recv(4))[0] #接收 服务端报头的长度 53 server_heaa_data=json.loads(self.socket.recv(server_head_len))#接收服务端报头信息 54 print(server_heaa_data) 55 server_data_size=server_heaa_data['data_size'] 56 server_data_name=server_heaa_data['name'] 57 with open(server_data_name,'wb') as f: 58 recv_size=0 59 while recv_size < server_data_size: # 开下载数据 60 data = self.socket.recv(1024) 61 f.write(data) 62 recv_size += len(data) 63 else: 64 print(self.socket.recv(1024).decode("utf-8")) 65 66 def put(self,d1): #上传操作 67 print(type(d1)) 68 struct_sek=self.socket.recv(4) 69 sek=struct.unpack('i',struct_sek)[0] 70 print("传来的sek%s"% sek) 71 print(d1[ 'data_size']) 72 if sek==d1[ 'data_size']: 73 print("已经上传") 74 else: 75 with open(d1["file_name"],'rb') as f: # 上传 76 f.seek(sek) 77 for i in f: 78 self.socket.send(i) 79 80 def login(self,name,pwd): # 登录 81 while True: #循环发送报头给服务端,让服务端做判断,返回执行结果; 82 cmd=input('请输入命令-------->').strip() 83 d1={"name": name, "pwd": pwd,"cmd":cmd,"flag":flag} 84 bytes_d1 = json.dumps(d1).encode("utf-8") 85 len_dl = len(bytes_d1) 86 struct_len = struct.pack("i", len_dl) 87 self.socket.send(struct_len) 88 self.socket.send(bytes_d1) 89 data_len=struct.unpack("i",self.socket.recv(4))[0] 90 res=self.socket.recv(data_len).decode("gbk") 91 print(res) 92 93 94 95 96 97 98 99 100 101 102 103 104 105 c=Client(("127.0.0.1",8080)) 106 c.run()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南