1-Python - ftp

about

本篇贴出手动使用多线程实现多用户ftp和使用socketserver实现ftp。

client

无论是手动实现的server,还是使用socketserver实现的server,client代码都不变。

client
#!/bin/bash
# -*- coding: utf-8 -*-


import socket
import struct
import json


class Client(object):

    def __init__(self, server_address):
        self.server_address = server_address
        self.connect_socket()

    def _mk(self, data):
        ''' 创建文件夹 '''
        self.send_msg(data)
        data = self.recv_msg()
        print(data['msg'])

    def _del(self, data):
        ''' delect dir ,不能删除文件 '''
        self.send_msg(data)
        data = self.recv_msg()
        print(data['msg'])

    def _touch(self, data):
        ''' 创建文件 '''
        self.send_msg(data)
        data = self.recv_msg()
        print(data['msg'])

    def _ls(self, data):
        ''' 查看当前目录下有什么文件或目录 '''
        # print('ls_data', data)
        self.send_msg(data)
        data = self.recv_msg()
        print(data['msg'])

    def _cd(self, data):
        ''' 切换目录 '''
        # print('cd_data', data)
        self.send_msg(data)
        data = self.recv_msg()
        print(data['msg'])

    def handle(self):
        ''' 解析指令并交给具体的方法处理 '''
        while 1:
            cmd = input('>>: ').strip()
            if not cmd: continue
            data = {"choice": cmd.split(' '), 'action_type': cmd.split(' ')[0]}
            if hasattr(self, '_%s' % data["choice"][0]):
                getattr(self, '_%s' % data["choice"][0])(data)
            else:
                print('invalid command')

    def send_msg(self, data):
        head_data = json.dumps(data).encode()
        head_size = struct.pack('i', len(head_data))
        self.request.send(head_size)
        self.request.send(head_data)

    def recv_msg(self):
        head_size = self.request.recv(4)
        st_data = struct.unpack('i', head_size)[0]
        head_data = self.request.recv(st_data).decode()
        return json.loads(head_data)

    def connect_socket(self):
        self.request = socket.socket()
        print(11, self.server_address)
        self.request.connect(self.server_address, )


if __name__ == '__main__':
    Client(('127.0.0.1', 8881)).handle()

server

手动使用多线程实现ftp
#!/bin/bash
# -*- coding: utf-8 -*-


import threading
import socket
import struct
import json


class MyFtp(object):

    def _mk(self, data):
        ''' 创建文件夹 '''
        # print('mk', data)
        data['msg'] = "mk msg"
        self.send_msg(data)

    def _del(self, data):
        ''' delect dir ,不能删除文件 '''
        # print('delect', data)
        data['msg'] = "delect msg"
        self.send_msg(data)

    def _touch(self, data):
        ''' 创建文件 '''
        # print('touch', data)
        data['msg'] = "touch msg"
        self.send_msg(data)

    def _ls(self, data):
        """ 查看当前目录下的文件 """
        # print('ls', data)
        data['msg'] = "ls msg"
        self.send_msg(data)

    def _cd(self, data):
        """ 切换目录 """
        # print('cd', data)
        data['msg'] = "cd msg"
        self.send_msg(data)

    def handle(self, request, client_address):
        self.request, self.client_address = request, client_address
        while True:
            try:
                data_msg = self.recv_msg()
                if hasattr(self, '_%s' % data_msg['action_type']):
                    getattr(self, '_%s' % data_msg['action_type'])(data_msg)
            except (ConnectionResetError, ConnectionAbortedError):
                break
        self.request.close()
        print('the {} disconnects...'.format(self.client_address))

    def send_msg(self, data):
        head_data = json.dumps(data).encode()
        head_size = struct.pack('i', len(head_data))
        self.request.send(head_size)
        self.request.send(head_data)

    def recv_msg(self):
        head_size = self.request.recv(4)
        st_data = struct.unpack('i', head_size)[0]
        head_data = self.request.recv(st_data).decode()
        return json.loads(head_data)


class MyThreadingTCPServer(object):
    request_queue_size = 5
    allow_reuse_address = False

    def __init__(self, server_address, request_handler_class):
        self.server_address = server_address
        self.RequestHandlerClass = request_handler_class
        self.request = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
        self.request.bind(server_address)
        self.request.listen(self.request_queue_size)

    def serve_forever(self):
        while True:
            print('waiting for the link.....')
            self.conn, self.client_address = self.request.accept()
            t = threading.Thread(target=self.RequestHandlerClass.handle,
                                 args=(self.RequestHandlerClass(), self.conn, self.client_address))
            t.start()

if __name__ == '__main__':
    # 手动实现并发
    obj = MyThreadingTCPServer(('127.0.0.1', 8881), MyFtp)
    obj.serve_forever()

使用socketserver实现多用户ftp
#!/bin/bash
# -*- coding: utf-8 -*-

import struct
import json
import socketserver


class MyFtp(socketserver.BaseRequestHandler):

    def _mk(self, data):
        ''' 创建文件夹 '''
        # print('mk', data)
        data['msg'] = "mk msg"
        self.send_msg(data)

    def _del(self, data):
        ''' delect dir ,不能删除文件 '''
        # print('delect', data)
        data['msg'] = "delect msg"
        self.send_msg(data)

    def _touch(self, data):
        ''' 创建文件 '''
        # print('touch', data)
        data['msg'] = "touch msg"
        self.send_msg(data)

    def _ls(self, data):
        """ 查看当前目录下的文件 """
        # print('ls', data)
        data['msg'] = "ls msg"
        self.send_msg(data)

    def _cd(self, data):
        """ 切换目录 """
        # print('cd', data)
        data['msg'] = "cd msg"
        self.send_msg(data)

    def handle(self):
        while True:
            print('waiting for the link.....')
            data_msg = self.recv_msg()
            if hasattr(self, '_%s' % data_msg['action_type']):
                getattr(self, '_%s' % data_msg['action_type'])(data_msg)

    def send_msg(self, data):
        head_data = json.dumps(data).encode()
        head_size = struct.pack('i', len(head_data))
        self.request.send(head_size)
        self.request.send(head_data)

    def recv_msg(self):
        head_size = self.request.recv(4)
        st_data = struct.unpack('i', head_size)[0]
        head_data = self.request.recv(st_data).decode()
        return json.loads(head_data)


if __name__ == '__main__':
    # 使用socketserver实现并发
    obj = socketserver.ThreadingTCPServer(('127.0.0.1', 8881), MyFtp)
    obj.serve_forever()

that's all
posted @ 2018-10-13 21:48  听雨危楼  阅读(375)  评论(0编辑  收藏  举报