博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
FTP
阅读量:2244 次
发布时间:2019-05-09

本文共 9282 字,大约阅读时间需要 30 分钟。

服务端:

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_err128 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()

 

转载于:https://www.cnblogs.com/sss4/p/6849614.html

你可能感兴趣的文章
RequestBody/ResponseBody处理Json数据
查看>>
springmvc请求参数获取的几种方法
查看>>
在eclipse中创建和myeclipse一样的包结构
查看>>
Java中的IO流
查看>>
java中的关键字
查看>>
如果某个方法是静态的,它的行为就不具有多态性
查看>>
优化Hibernate所鼓励的7大措施
查看>>
Java 8系列之重新认识HashMap
查看>>
HashMap 、 ArrayList、String 重写了equals方法 而Object类(比如User)没有重写
查看>>
Servlet的生命周期
查看>>
Object中的getClass()返回的是当前运行的类
查看>>
加载驱动程序的方法
查看>>
深入理解java异常处理机制
查看>>
object类的基本方法
查看>>
回答阿里社招面试如何准备,顺便谈谈对于Java程序猿学习当中各个阶段的建议
查看>>
Dubbo分布式服务框架入门(附工程)
查看>>
两年Java开发工作经验面试总结
查看>>
作为Java面试官--谈谈一年来的面试总结
查看>>
两年Java程序员面试经
查看>>
面试心得与总结---BAT、网易、蘑菇街
查看>>