ftp

 
优点: 允许多用户同时使用
    文件一致性检测
    支持断点续传
 
缺点:   没有权限管理
 
#!/usr/bin/env python3
# -- coding:utf-8 --

import socketserver, json
import hashlib
import os, sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from moudle import mymd5

ip_port = ("0.0.0.0", 85)

class Myserver(socketserver.BaseRequestHandler):

    def handle(self):
        conn = self.request
        conn.send(bytes("Welcome to use jyall tfp-server.", 'utf8'))
        while True:
            recv_msg = conn.recv(1024)
            print("Recv msg: {}".format(recv_msg.decode() ))
            recv_json = json.loads(recv_msg.decode() )
            msg_size = recv_json.get("filesize")
            recv_active = recv_json.get("active")
            if hasattr(self, "client_{}".format(recv_active)):
                func = getattr(self, "client_{}".format(recv_active))
                func(recv_json)
            else:
                print("Action {} isn't supported.".format(recv_active))

    def client_put(self, *args, **kwargs):
        self.request.send(bytes(json.dumps({"status": "Ready"}), 'utf8'))
        filename = "/data/zhuanti_zip/{}".format(args[0].get("absfilename").split("\\")[-1] )
        filesize = args[0].get("filesize")
        filemd5 = args[0].get("filemd5")
        print("File: {}, Size: {}".format(filename,filesize))
        f = open(filename, 'wb')
        recv_size = 0
        while recv_size < filesize:
            data = self.request.recv(1024)
            f.write(data)
            recv_size += len(data)
        f.close()
        if filemd5 == mymd5.md5file(filename):
            print("\033[32;1mRecv {} Sucessful\033[0m".format(filename))
        else:
            print("\033[31;1mRecv {} False\033[0m".format(filename))

    def client_get(self, *args, **kwargs):
        self.filename = "/data/zhuanti_bak/{}".format(args[0].get("absfilename"))
        if os.path.isfile(self.filename):
            self.filesize = os.stat(self.filename).st_size
            self.filemd5 = mymd5.md5file(self.filename)
            self.status = "exist"
            send_stat_msg = {"filename": self.filename, "filesize": self.filesize, "filemd5": self.filemd5, "status": self.status}
            for key in send_stat_msg:
                print("\033[36;1m{:<20} {}\033[0m".format(key, self.__dict__[key]))

            self.request.sendall(bytes(json.dumps(send_stat_msg), 'utf8'))
            recv_data = self.request.recv(1024)
            recv_data_json = json.loads(recv_data.decode())
            if recv_data_json["status"] == "Ready":
                print("Server Send {} , Start Put {} ".format(json.loads(recv_data.decode())["status"], self.filename))
                f = open(self.filename, 'rb')
                f.seek(recv_data_json["filesize"])
                for line in f:
                    self.request.send(line)
                f.close()
                print("\033[4;32;1mSend file [ {} ] done.\033[0m".format(self.filename))
        else:
            self.request.send(bytes(json.dumps({"status":"notexist"}), 'utf8'))
            print("\033[5;31;1mfile {} not exist.\033[0m".format(self.filename))


if __name__ == "__main__":
    server = socketserver.ThreadingTCPServer(ip_port, Myserver)
    server.serve_forever()
ftp-server

 

#!/usr/bin/env python
# -- coding:utf-8 --

import socket
import os, sys, json
import hashlib

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from conf import ftpconf
from module import view_bar


# def fileexist(func):
#     def innser(*args, **kwargs):
#         if os.path.isfile(*args, **kwargs):
#             return func(*args, **kwargs)
#         else:
#             print("file not exist.")
#             return
#
# @fileexist


class Filemsg:

    def __init__(self, absfilename):
        self.filesize = os.stat(absfilename).st_size
        self.filemd5 = self.GetFileMd5(absfilename)


class Ftp_client(Filemsg):

    def __init__(self, active, absfilename):
        self.active = active
        self.absfilename = absfilename
        # self.filename = absfilename.split(os.sep)[-1]

        if hasattr(self, "client_{}".format(self.active)):      # 判断是否有用户输入的方法
            func = getattr(self, "client_{}".format(self.active))
            func()
        else:
            print("\033[31;1mPlease input: [put|get] file\033[0m")

    def client_put(self):
        if os.path.isfile(self.absfilename):                      # 判断本地文件是否存在
            super(Ftp_client, self).__init__(self.absfilename)    # 获取文件信息(大小,md5值)
            print("Ready to put ", self.absfilename)
            for key in self.__dict__:
                print("\033[36;1m{:<20} {}\033[0m".format(key, self.__dict__[key]))

            sk.send(bytes(json.dumps(self.__dict__), encoding='utf8'))
            recv_data = sk.recv(1024)

            if json.loads(recv_data.decode())["status"] == "Ready":
                print("Server Send {} , Start Put {} ".format(json.loads(recv_data.decode())["status"], cmd_list[1]))
                f = open(cmd_list[1], 'rb')
                send_size = 0
                for line in f:
                    sk.send(line)
                    send_size += len(line)
                    view_bar.view_bar(send_size, self.filesize)
                f.close()
                print("\033[4;32;1m\nSend file [ {} ] done.\033[0m".format(self.absfilename))
        else:
            print("\033[31;1mFile [ {} ] is not exist.\033[0m".format(cmd_list[1]))

    def client_get(self):
        print("Ready to get ", self.absfilename)
        for key in self.__dict__:
            print("\033[36;1m{:<20} {}\033[0m".format(key, self.__dict__[key]))

        sk.sendall(bytes(json.dumps(self.__dict__), encoding='utf8'))
        recv_filemsg = sk.recv(1024)
        recv_filemsg_json = json.loads(recv_filemsg.decode())

        for key in recv_filemsg_json:
            print("\033[34;1m{:<20} {}\033[0m".format(key, recv_filemsg_json[key]))

        if recv_filemsg_json["status"] == "exist":
            get_path = "C:\\Users\\xu.lin\\Desktop\\专题\\{}".format(self.absfilename)
            file_size = recv_filemsg_json.get("filesize")

            if os.path.isfile(get_path):
                super(Ftp_client, self).__init__(get_path)
                print("[ {} ] is exist and size is {}, So starting resume.".format(get_path, self.filesize))

                recv_size = self.filesize
                fh = open(get_path, 'ab')

            else:
                print("[ {} ] isn't exist, So starting normal get.".format(get_path))

                recv_size = 0
                fh = open(get_path, 'wb')

            sk.send(bytes(json.dumps({"status": "Ready", "filesize": recv_size}), 'utf8'))

            fh.seek(recv_size)
            while recv_size < file_size:
                data = sk.recv(1024)
                fh.write(data)
                recv_size += len(data)
                view_bar.view_bar(recv_size, file_size)
            fh.close()

            if recv_size == file_size:
                print("\033[4;32;1m\nRecv {} Sucessful.\033[0m".format(self.absfilename))
        else:
            print("\033[4;31;1mFile [ {} ] is not exist.\033[0m".format(self.absfilename))

    @staticmethod
    def GetFileMd5(filename):
        myhash = hashlib.md5()
        f = open(filename, 'rb')
        while True:
            b = f.read(8096)
            if not b:break
            myhash.update(b)
        f.close()
        return myhash.hexdigest()


if __name__ == "__main__":

    sk = socket.socket()
    print(ftpconf.ip_port)
    sk.connect(ftpconf.ip_port)
    welcome_msg = sk.recv(1024)
    print(welcome_msg.decode())

    while True:
        send_data = input(">>: ").strip()
        cmd_list = send_data.split()
        if len(cmd_list) < 2: continue           # 判断用户输入参数个数,put filename
        obj = Ftp_client(cmd_list[0], cmd_list[1])

    sk.close()
ftp-client

 

 

posted @ 2017-05-19 15:10  xu.lin  阅读(185)  评论(0)    收藏  举报