十八.Python模拟FTP文件上传-程序员宅基地

技术标签: # Python  

Python 模拟FTP断点续传并发服务器

 

#配置文件

#服务器配置文件

[server_config]
ip=127.0.0.1
port=8006
buffersize=1024
encoding=utf-8

#服务器用户数据 

[tom]
username=tom
password=123456
[alex]
username=alex
password=123456

 

#FTP服务器代码

#程序入口
import optparse
import sys,os
#os.path.dirname 获取文件的文件夹路径
path=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(path)
from core import main
class ftt_server:
   def __init__(self):
      self.option = optparse.OptionParser()
      self.option.add_option("-i", "--ip", dest="ip")
      self.option.add_option("-p", "--port", dest="port")
      self.opt, self.args = self.option.parse_args()
      self.one()
   def one(self):
      main.main(self.opt, self.args)

if __name__=="__main__":
   ftt_server()

#服务器监听程序
import socketserver
import optparse
import configparser
import os
from core import server
class main():
    def __init__(self,opt,args):
        args=args
        self.option=opt
        self.config=configparser.ConfigParser()
        self.config.read(os.path.dirname(os.path.dirname(__file__))+"/conf/config.ini")
        self.server=server
        self.BaseDir=os.path.dirname(os.path.dirname(__file__))
        self.validate(opt, args)
    def validate(self, options, args):
        cmd=args[0]
        if hasattr(self,cmd):
            fun=getattr(self,cmd)
            fun()
    def start(self):
        ip=self.option.ip
        port=self.option.port
        if ip=="":
            ip=self.getConfig("server_config","ip")
        if port=="":
            port=self.getConfig("server_config","port")
        print("server start Successful!")
        self.sock_ser=socketserver.ThreadingTCPServer((ip,int(port)),self.server.server_handler)
        self.sock_ser.serve_forever()

    def help(self):
        pass

    def getConfig(self,section,attribute):
        return self.config.read(section,attribute)


#服务器主程序
import socketserver
import configparser
import os
import json
import sys
class server_handler(socketserver.BaseRequestHandler):
    def handle(self):
        self.config_name="server_config"
        self.BaseDir=os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
        self.config_Path=os.path.join(self.BaseDir,"conf","config.ini")
        self.user_config=os.path.join(self.BaseDir,"conf","user.ini")
        self.buffersize=int(self.getIni(self.config_Path,self.config_name,"buffersize"))
        self.encoding=self.getIni(self.config_Path,self.config_name,"encoding")
        self.currenSize=0
        data = self.request.recv(self.buffersize).decode(self.encoding)
        data = json.loads(data)
        print(data)
        fun = data["action"]
        if fun=="login":
            con=configparser.ConfigParser()
            con.read(self.user_config)
            if con.has_section(data["user"]):
                if con.get(data["user"],"password")==data["password"]:
                    self.currenDir=data["user"]
                    self.request.sendall("504".encode("utf-8"))
                    self.name=data["user"]
                    self.home=os.path.join(self.BaseDir, "home",data["user"])
                    self.currenDir=self.home
                    self.interception()
                else:
                    self.request.sendall("404".encode("utf-8"))
    

    def getIni(self,path,section,attribute):
        conf = configparser.ConfigParser()
        conf.read(path)
        return conf.get(section, attribute)
    #交互
    def interception(self):
        while 1:
            print("wait recv....")
            data=self.request.recv(self.buffersize)
            data=json.loads(data)
            print(data)
            fun=data["action"]
            if hasattr(self,fun):
                func=getattr(self,fun)
                func(**data)
            else:
                self.request.sendall("400".encode("utf-8"))
    #cd文件夹切换功能
    def cd(self,**kwargs):
        position=kwargs["position"]
        if position=="../":
            self.currenDir =os.path.dirname(self.currenDir)
        else:
            self.currenDir=os.path.join(self.currenDir,position)
        self.request.sendall(os.path.basename(self.currenDir).encode(self.encoding))
    #创建文件夹功能
    def mkdir(self,**kwargs):
        print(kwargs)
        position=kwargs["position"]
        mkfile=os.path.join(self.currenDir,position)
        try:
            if "/" in position or "\\" in position:
                os.makedirs(mkfile)
            else:
                os.mkdir(mkfile)
        except Exception as e:
            self.request.sendall("605".encode(self.encoding))
        self.request.sendall("606".encode(self.encoding))
    #显示当前文件夹内容
    def ls(self,**kwargs):
        dir_con=os.listdir(self.currenDir)
        self.request.sendall(str(dir_con).encode("utf-8"))
    #文件断点续传功能
    def put(self,**kwargs):
        file_name=kwargs["file_name"]
        file_size=kwargs["file_size"]
        target=kwargs["target"]
        self.target_file=os.path.join(self.currenDir,target,file_name)
        if os.path.exists(self.target_file):
            self.currenSize=os.stat(self.target_file).st_size
            if self.currenSize>=file_size:
                self.request.sendall("801".encode(self.encoding))
                return
            else:
                self.request.sendall("802".encode(self.encoding))
                data=self.request.recv(self.buffersize).decode(self.encoding)
                if data=="Y":
                    f = open(self.target_file, "ab")
                    self.request.sendall(str(self.currenSize).encode(self.encoding))
                else:
                    f = open(self.target_file, "wb")
        else:
            f = open(self.target_file, "wb")
            self.request.sendall("803".encode("utf-8"))

        while self.currenSize<file_size:
            data=self.request.recv(self.buffersize)
            f.write(data)
            self.currenSize+=len(data)
            self.progess(self.currenSize, file_size)
    #文件上传进度
    def progess(self,curren,total):
        rate = int(curren / total * 100)
        if rate > 0:
            st=sys.stdout
            st.write("%s%% %s \r\n"%(rate,"*"*rate))
            st.flush()
            if rate==100:
                print("upload finish!")


#FTP客户端

#配置文件

[client_config]
buffer_size=1024

#客户端代码

#FTP客户端程序
from socket import *
import sys,os
import optparse
import json
import configparser
path=os.path.dirname(os.path.dirname(__file__))
sys.path.append(path)

#状态字典
dicts={"504":"登陆成功!",
      "404":"用户或者密码有误!登陆失败!",
      "400":"Input Error",
       "606":"create success",
       "605":"create fail",
       "801":"the file is existing",
       "802":"the file is existing,but not enough",
       "803":"the file start upload..."
      }

class client_handler:
    def __init__(self):
        self.option=optparse.OptionParser()
        self.option.add_option("-i", "--ip", dest="ip")
        self.option.add_option("-p", "--port", dest="port")
        self.option.add_option("-u", "--user", dest="username")
        self.option.add_option("-P", "--password", dest="password")
        self.conf = configparser.ConfigParser()
        self.Base_Dir=os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
        self.buffersize= int(self.bufferSize())
        self.size_file=0
        options, args = self.option.parse_args()
        self.task(options,args)
    def task(self, options, args):
        port=options.port
        if int(port)>0 and int(port)<65535:
            self.make_connection(options,args)
        else:
            exit("the port is in 0 and 65535!")
    def make_connection(self, options, args):
        self.sclient = socket(AF_INET, SOCK_STREAM)
        self.sclient.connect((options.ip, int(options.port)))
        self.login()
    def login(self):
        name=input("请输入用户名>>")
        password=input("请输入密码>>")
        self.json = {"action": "login", "user": name, "password": password}
        self.sclient.send(json.dumps(self.json).encode("utf-8"))
        data=self.sclient.recv(self.buffersize).decode("utf-8")
        # print(data)
        if data=="504":
            self.name=name
            print(dicts[data])
            while 1:
                code=input("[%s]"%self.name)
                cmd_list=code.split()
                if hasattr(self,cmd_list[0]):
                    fun=getattr(self,cmd_list[0])
                    fun(*cmd_list)
        else:
            print(dicts[data])
    def bufferSize(self):
        self.conf_path=os.path.join(self.Base_Dir,"conf","config.ini")
        self.conf.read(self.conf_path)
        return self.conf.get("client_config", "buffer_size")

    def put(self,*cmd_list):
        # print("put...")
        action,location,target=cmd_list
        file_name=os.path.basename(location)
        file_size=os.stat(location).st_size
        data={"action":action,
              "file_name":file_name,
              "file_size":file_size,
              "target":target}
        self.sclient.sendall(json.dumps(data).encode("utf-8"))
        data=self.sclient.recv(self.buffersize).decode("utf-8")
        self.parseNum(data)
        if data=="801":
            return
        elif data=="802":
            choice=input("the file is existing,but not enough,is continue?<Y/N>")
            if choice.upper()=="Y":
                self.sclient.sendall(choice.upper().encode("utf-8"))
                self.size_file =int(self.sclient.recv(self.buffersize).decode("utf-8"))
            else:
                self.sclient.sendall(choice.upper().encode("utf-8"))
        elif data=="803":
            pass
        f=open(location,"rb")
        f.seek(self.size_file)
        while self.size_file<file_size:
            fdata=f.read(self.buffersize)
            self.sclient.sendall(fdata)
            self.size_file+=len(fdata)
            self.progess(self.size_file, file_size)
    def cd(self,*cmd_list):
        # print("cd...")
        action,position=cmd_list
        data={"action":action,
              "position":position}
        data=json.dumps(data)
        self.sclient.sendall(data.encode("utf-8"))
        data=self.sclient.recv(self.buffersize).decode("utf-8")
        self.name=data
    def ls(self,*cmd_list):
        action=cmd_list[0]
        data={"action":action}
        data=json.dumps(data)
        self.sclient.sendall(data.encode("utf-8"))
        con=self.sclient.recv(self.buffersize).decode("utf-8")
        con=list(con)
        for i in con:
            print(i,end="\r")
    def mkdir(self,*cmd_list):
        print("mkdir...")
        action,position=cmd_list
        data={"action":action,
              "position":position
              }
        data=json.dumps(data)
        self.sclient.sendall(data.encode("utf-8"))
        con=self.sclient.recv(self.buffersize).decode("utf-8")
        print(dicts[con])
    def parseNum(self,st):
        print(dicts[st])
    def progess(self,curren,total):
        rate=int(curren/total*100)
        if rate > 0:
            st=sys.stdout
            st.write("%s%% %s\r\n"%(rate,"*"*rate))
            st.flush()
            if rate==100:
                print("upload finish!")

#程序入口
if __name__=="__main__":
    client_handler()








启动

#服务器启动
python ftp_server start -i 127.0.0.1 -p 8006

#客户端启动
python ftp_client -i 127.0.0.1 -p 8006

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_39663113/article/details/85813523

智能推荐

Redis 命令-程序员宅基地

文章浏览阅读166次。Redis 命令Redis 命令用于在 redis 服务上执行操作。要在 redis 服务上执行命令需要一个 redis 客户端。Redis 客户端在我们之前下载的的 redis 的安装包中。语法Redis 客户端的基本语法为:$ redis-cli实例以下实例讲解了如何启动 redis 客户端:启动 redis 客户端,打开终端并输入命令 redis-cli。该命

个人笔记5-程序员宅基地

文章浏览阅读372次。个人笔记

POJ 2965 The Pilots Brothers' refrigerator (枚举)-程序员宅基地

文章浏览阅读955次。POJ 2965 The Pilots Brothers' refrigerator (枚举)

信驰达BLE 5.0低功耗蓝牙模块使用 (AT指令串口透传) RSBRS02ABR_蓝牙5.0能被串口助手检测到吗-程序员宅基地

文章浏览阅读1.5k次。信驰达蓝牙模组信驰达透传固件功能特点:使用简单,无需任何蓝牙协议栈应用经验;支持蓝牙 5.0 协议栈。价格便宜,价格便宜,价格便宜 (重要的事情只说三遍)1. 环境准备1.1 硬件环境USB转TTL 1个 + 杜邦线 6 根RSBRS02ABR 模块 1个 1.2软件准备准备驱动安装包CP210x_Universal_Windows_Driver:准备串口调试助手工具UartAssist : 下载链接准备手机APP:nRf-Connect _蓝牙5.0能被串口助手检测到吗

程序员练级攻略(转自coolshell 陈皓)-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏8次。前言你是否觉得自己从学校毕业的时候只做过小玩具一样的程序?走入职场后哪怕没有什么经验也可以把以下这些课外练习走一遍(朋友的抱怨:学校课程总是从理论出发,作业项目都看不出有什么实际作用,不如从工作中的需求出发)建议:不要乱买书,不要乱追新技术新名词,基础的东西经过很长时间积累而且还会在未来至少10年通用。回顾一下历史,看看历史上时间线上技术的发展,你才能明白明天会是什么样。一

什么是机器学习,一文让你了解机器学习的历史和真谛-程序员宅基地

文章浏览阅读2.1w次,点赞19次,收藏58次。作者:计算机的潜意识在本篇文章中,我将对机器学习做个概要的介绍。本文的目的是能让即便完全不了解机器学习的人也能了解机器学习,并且上手相关的实践。这篇文档也算是 EasyPR开发的番外篇,从这里开始,必须对机器学习了解才能进一步介绍EasyPR的内核。当然,本文也面对一般读者,不会对阅读有相关的前提要求。在进入正题前,我想读者心中可能会有一个疑惑:机器学习有什么重要性,以至于要阅读完

随便推点

IDEA异常 cannot resolve symbol 'HttpServletRequest'-程序员宅基地

文章浏览阅读1.2w次,点赞15次,收藏14次。IDEA异常 cannot resolve symbol ‘HttpServletRequest’如图一在IDEA出现的问题,java编辑器找不到HttpServletRequest包,只需将tomcat中的库倒进来即可如图二。步骤file->project structure->modules->选择对应的项目->dependencies->右侧加号libraries->添加tomcat的libr

拦截器interceptors基本介绍-程序员宅基地

文章浏览阅读3k次。拦截器是动态拦截Action调用的对象.它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行.同时也是提供了一种可以提取action中可重用的部分的方式.拦截器必须是无状态的,不能保证为每一个请求或者action创建一个实例.拦截器可以选择短路一个action调用,然后返回一个结果码(如com.opensymphony.xwork_interceptors

视觉SLAM中动态场景剔除总结_视觉slam怎么去除动态特征点-程序员宅基地

文章浏览阅读5k次,点赞2次,收藏26次。目前看了两篇论文总结一下:DS-SLAM A Semantic Visual SLAM towards dynamic environments (2018):这篇文章基于ORB_SLAM2, 利用帧间图像的光流跟踪,进行一致性检验(利用了基础矩阵,判断点极线距离的大小),找到运动的像素点。同时另开辟一个线程做Segmet 场景语义分割(只能分割20种物体),认为人是可能运动的物体,如果运动的..._视觉slam怎么去除动态特征点

单源最短路径SSSP之Bellman-Ford算法-程序员宅基地

文章浏览阅读722次。Bellman-Ford算法和Dijkstra算法都是求解图的最短路径的算法。Bellman是求单源点到各个顶点的最短路径,适用条件为有向或无向图,权重可为负值。当存在负权环路时,算法返回一个false值。该算法效率比较低,需要对边进行 |V|- 1 次松弛操作Bellman-Ford算法寻找单源最短路径的时间复杂度为O(V*E)。(V为给定图的顶点集合,E为给定图的边集合)两者区别在于:..._sssp

Upgrade Oracle Database 11.1.0 to 12.1.0 for EBS R12.1.3_ins-32016-程序员宅基地

文章浏览阅读1.7k次。vm oracle linux7 安装 Oracle E-Business 12.1说明:在执行下面步骤之前,需要提前申请oracle账号,下载12.1介质。注册oracle账号链接:http://metalink.oracle.com/oracle linux7 和Oracle E-Business 12.1下载链接:https://edelivery.oracle.com文章目录vm oracle linux7 安装 Oracle E-Business 12.1一、操作系统要求1.1、在 v_ins-32016

第二章思维导图_今天的作业,自己绘制第二章有理数的思维导图,发到老师的作业小程序-程序员宅基地

文章浏览阅读572次。_今天的作业,自己绘制第二章有理数的思维导图,发到老师的作业小程序

推荐文章

热门文章

相关标签