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