服务端:

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

 

posted on 2017-05-13 17:08  Martin8866  阅读(254)  评论(0编辑  收藏  举报