• python使用selector模块编写FTP


    server

    import os
    import socket
    import time
    import selectors
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    
    
    class selectFtpServer(object):
    
        def __init__(self):
            self.dic = {}
            self.hasReceived = 0
            self.sel = selectors.DefaultSelector()
            self.create_socket()
            self.handler()
    
        def create_socket(self):
            server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server.bind(("127.0.0.1", 8885))
            server.listen(5)
            self.sel.register(server, selectors.EVENT_READ, self.accept)
            print("服务端已开启,等待用户连接...")
    
        def handler(self):
            while True:
                events = self.sel.select()
                for key, mask in events:
                    call_back = key.data
                    call_back(key.fileobj, mask)
    
        def accept(self, server, mask):
            conn, addr = server.accept()
            print("from %s %s connected" % addr)
            self.sel.register(conn, selectors.EVENT_READ, self.read)
    
            self.dic[conn] = {}
    
        def read(self, conn, mask):
            try:
                if not self.dic[conn]:
                    data = conn.recv(1024)
                    cmd, filename, filesize = str(
                        data, encoding='utf-8').split('|')
                    self.dic = {
                        conn: {
                            "cmd": cmd,
                            "filename": filename,
                            "filesize": int(filesize)}}
                    print(self.dic)
                    if cmd == 'put':
                        conn.send(bytes("OK", encoding='utf8'))
    
                    if self.dic[conn]['cmd'] == 'get':
                        file = os.path.join(BASE_DIR, "download", filename)
    
                        if os.path.exists(file):
                            fileSize = os.path.getsize(file)
                            send_info = '%s|%s' % ('YES', fileSize)
                            conn.send(bytes(send_info, encoding='utf8'))
                        else:
                            send_info = '%s|%s' % ('NO', 0)
                            conn.send(bytes(send_info, encoding='utf8'))
                else:
                    if self.dic[conn].get('cmd', None):
                        print(self.dic[conn].get('cmd'))
                        cmd = self.dic[conn].get('cmd')
                        print(cmd)
                        if hasattr(self, cmd):
                            func = getattr(self, cmd)
                            func(conn)
                        else:
                            print("error cmd!")
                            conn.close()
                    else:
                        print("error cmd!")
                        conn.close()
    
            except Exception as e:
                print('error', e)
                self.sel.unregister(conn)
                conn.close()
    
        def put(self, conn):
            self.hasReceived = 0
            fileName = self.dic[conn]['filename']
            fileSize = self.dic[conn]['filesize']
            path = os.path.join(BASE_DIR, "upload", fileName)
            while self.hasReceived < fileSize:
                recv_data = conn.recv(1024)
                self.hasReceived += len(recv_data)
    
                with open(path, 'wb') as f:
                    f.write(recv_data)
                if fileSize == self.hasReceived:
                    if conn in self.dic.keys():
                        self.dic[conn] = {}
                    print("%s上传完毕!" % fileName)
    
        def get(self, conn):
    
            filename = self.dic[conn]['filename']
            path = os.path.join(BASE_DIR, "download", filename)
            if str(conn.recv(1024), 'utf-8') == "second_active":
                with open(path, 'rb') as f:
                    for line in f:
                        conn.send(line)
                self.dic[conn] = {}
                print('文件下载完毕!')
    
    
    if __name__ == '__main__':
        ftp = selectFtpServer()
    

      

    client

    import socket
    import time
    import os
    
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    
    
    class selectFtpClient():
    
        def __init__(self):
            self.createSocket()
            self.command_out()
    
        def createSocket(self):
            try:
                self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.client.connect(("127.0.0.1", 8885))
                print('连接FTP服务器成功!')
            except Exception as e:
                print("error: ", e)
    
        def command_out(self):
            while True:
                cmd = input('>>>').strip()
                if cmd == 'exit':
                    break
                cmd, file = cmd.split()
                if hasattr(self, cmd):
                    func = getattr(self, cmd)
                    func(cmd, file)
                else:
                    print('调用错误!')
    
        def get(self, cmd, file):
            pass
    
        def put(self, cmd, file):
            if os.path.isfile(file):
                fileName = os.path.basename(file)
                fileSize = os.path.getsize(file)
                fileInfo = '%s|%s|%s' % (cmd, fileName, fileSize)
                self.client.send(bytes(fileInfo, encoding='utf8'))
                recvStatus = self.client.recv(1024)
                print('recvStatus', recvStatus)
                hasSend = 0
                if str(recvStatus, encoding='utf8') == "OK":
                    with open(file, 'rb') as f:
                        while fileSize > hasSend:
                            contant = f.read(1024)
                            recv_size = len(contant)
                            self.client.send(contant)
                            hasSend += recv_size
                            s = str(int(hasSend / fileSize * 100)) + "%"
                            print("正在上传文件:" + fileName + "   已经上传:" + s)
                    print('%s文件上传完毕' % (fileName,))
            else:
                print('文件不存在')
    
    
    if __name__ == '__main__':
        c = selectFtpClient()
    

      

  • 相关阅读:
    【文字检测算法整理】
    【LDA】周志华
    【PCA】周志华
    【SVM】周志华
    4.1、顺序栈的实现(java实现)
    3.1、双向循环链表(java实现)
    5、链表队列(java实现)
    4、链栈的实现(java代码)
    3、循环链表(java实现)
    CommonsMultipartFile 转为 File 类型
  • 原文地址:https://www.cnblogs.com/xiao-apple36/p/9624245.html
Copyright © 2020-2023  润新知