python之ftp与paramiko与hasattr与getattr

为了方便树莓派和电脑上相互传输数据文件的传输。也就是上传和下载文件,我自己就写了一个ftp

主要是运用到hasattr与getattr

先看一下服务器上的程序吧

# _*_coding:utf-8_*_
# /usr/bin/env python3
# Author:book Miki

import socketserver
import json
import os

class MysocketHand(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                self.data = self.request.recv(1024)
                commond = json.loads(self.data)
                action = commond["action"]
                if hasattr(self, action):
                    fun = getattr(self, action)
                    fun(commond)
                print("{} wrote:".format(self.client_address[0]))
                print(self.data.decode())
            except ConnectionResetError as e:
                print('eer', e)
                break

    def put(self, *args):
        ''' 接收客户端文件 '''
        cmd_dir = args[0]
        filename = cmd_dir['filename']
        filesize = int(cmd_dir['filesize'])
        if os.path.isfile(filename):
            f = open(filename + '.new', 'wb')
        else:
            f = open(filename, 'wb')

        self.request.send(b'200 ok')
        recv_size = 0
        recv_size = int(recv_size)
        while recv_size < filesize:
            recv_data = self.request.recv(1024)
            f.write(recv_data)
            recv_size += len(recv_data)
            print("已经加载 %s :" % (recv_size/filesize*100))
            print(recv_size, 'recv size', filesize, 'file size')

        else:
            print(' %s is ok' % filename)
            f.close()

    def get(self, *args):
        filename = args[0]['filename']

        msg_dir = {
            'yes_or_no': 'none',
            'file_size': 0
        }
        if os.path.isfile(filename):
            file_size = os.stat(filename).st_size
            msg_dir['yes_or_no'] = 'yes'
            msg_dir['file_size'] = file_size
            self.request.send(json.dumps(msg_dir).encode())
            queren = self.request.recv(1024).decode()
            if queren == 'y':
                f = open(filename, 'rb')
                for line in f:
                    self.request.send(line)
                f.close()
            else:
                print('error')

        else:
            msg_dir['yes_or_no'] = 'no'
            self.request.send(json.dumps(msg_dir).encode())


if __name__ == '__main__':
    HOST, POST = 'localhost', 9999
    sever = socketserver.ThreadingTCPServer((HOST, POST), MysocketHand)
    sever.serve_forever()

接下来是客户端的

# _*_coding:utf-8_*_
# /usr/bin/env python3
# Author:book Miki

import socket
import os
import json


class Myclient(object):
    def __init__(self, ip, port):
        self.client = socket.socket()
        self.ip = ip
        self.port = port
    def help(self):
        msg = '''
        ls
        cd
        pwd
        get filename
        put filename
        '''
    def connent(self):
        self.client.connect((self.ip, self.port))

    def interactive(self):
        while True:
            msg = input('>>;')
            if len(msg) == 0:
                continue
            mst_cmd = msg.split()[0]
            if hasattr(self, "cmd_%s" % mst_cmd):
                fun = getattr(self, 'cmd_%s' % mst_cmd)
                fun(msg)
            else:
                self.help()
    def cmd_put(self,*args):
        cmd_split = args[0].split()
        if len(cmd_split) > 1:
            filename = cmd_split[1]
            if os.path.isfile(filename):
                filesize = os.stat(filename).st_size
                msg_dic = {
                    "action": "put",
                    "filename": filename,
                    "filesize": filesize
                }
                self.client.send(json.dumps(msg_dic).encode())
                # 防止粘包
                self.client.recv(1024)
                f = open(filename, 'rb')
                for line in f:
                    self.client.send(line)
            else:
                print(filename, " is none")
    def cmd_get(self,*args):
        cmd_split = args[0].split()
        if(len(cmd_split)>1):
            filename = cmd_split[1]
            msg_dic = {
                "action": "get",
                "filename": filename
            }
            self.client.send(json.dumps(msg_dic).encode())
            action = json.loads(self.client.recv(1024))
            yes_or_no = action['yes_or_no']
            if yes_or_no == 'yes':
                queren = input('downland %s y/n' % filename)
                self.client.send(queren.encode())
                if queren == 'y':
                    if os.path.isfile(filename):
                        f = open(filename+'new','wb')
                    else:
                        f = open(filename,'wb')
                    file_size = action['file_size']
                    recv_size = 0
                    while file_size > recv_size:
                        recv_data = self.client.recv(1024)
                        recv_size += len(recv_data)
                        f.write(recv_data)
                        print('已下载 : %s %%' % (recv_size / file_size *100))
                    else:
                        print('下载成功')
                        f.close()
                else:
                    print('取消下载')
            else:
                print(json.loads(self.client.recv(1024)).decode())


a = Myclient('192.168.43.140', 9999)
a.help()
a.connent()
a.interactive()

如此一来我在树莓派上的数据就可以发送到本地了

可是我就在今天发现了prarmiko这个模块我真的是气死了因为他只需要三五行代码就解决了我两百多行代码的问题

请看

# 树莓派实证有效
import paramiko
transport =paramiko.Transport(('192.168.43.140',22))
transport.connect(username='pi',password='raspberrypi')
sftp = paramiko.SFTPClient.from_transport(transport)
sftp.put('text1', '/home/pi/python_code/python_ssh/socketsever.py')
# sftp.get('remove_path', 'local_path')
transport.close()

是不是太简单了?但是也不亏哈哈哈,自己写了一个ftp的简易版也算是了解了其中的奥妙了

原文地址:https://www.cnblogs.com/BookMiki/p/10198262.html