• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell
您的位置:首页 > 脚本语言 >python > python实现可以断点续传和并发的ftp程序

python实现可以断点续传和并发的ftp程序

作者: 字体:[增加 减小] 来源:互联网

通过本文主要向大家介绍了python 断点续传,python中的断点续传,ftp断点续传,ftp支持断点续传吗,java ftp断点续传等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

前言

下载文件时,最怕中途断线,无法成功下载完整的文件。断点续传就是从文件中断的地方接下去下载,而不必重新下载。这项功能对于下载较大文件时非常有用。那么这篇文章就来给大家分享如何利用python实现可以断点续传和并发的ftp程序。

一、要求

     1、用户md5认证

     2、支持多用户同时登陆(并发)

     3、进入用户的命令行模式,支持cd切换目录,ls查看目录子文件

     4、执行命令(ipconfig)

     5、传输文件:

    a、支持断点续传

    b、传输中显示进度条

二、思路

1.客户端用户登录和注册:

     a、客户端仅提供用户名和密码,选择登录或注册,

     b、服务器端进行注册并将加密后的密码写入文件,最后返回给客户端是否登录或注册成功

2.ls和cd命令

     a、客户端输入命令,服务器端处理并返回给客户端

3.执行命令:

     a、客户端发送需要执行的命令

     b、服务器端执行命令,并返回客户端需要接收该命令的次数s=r[0]+1,其中r=divmod(结果总长度,1024)

     c、客户端收到次数,告诉服务端已经收到

     d、服务端发送执行结果,客户端进行for循环接收该结果

4.发送文件:

     a、客户端输入文件路径(测试版路径为:f.png),发送文件名和文件大小

     b、服务器端检测指定目录是否含有该文件,如果没有,返回给客户端字符串s,即从头开始发送start,has_recv=0
如果有,即需要断点续传,返回给客户端已经上传了多少has_recv

     c、客户端接收返回值,并seek到has_recv的位置,进行循环收发,打印当前进度,直到传输完毕。

注:本程序可循环接收用户选择传输文件和执行命令

三、代码

配置文件:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
 
BASE_DIR = os.path.dirname(os.path.dirname(__file__)) #配置文件的上层目录
NEW_FILENAME=os.path.join(BASE_DIR,'view')       #新文件目录
NAME_PWD=os.path.join(BASE_DIR,'db','name_pwd')    #用户名和密码目录
USER_FILE=os.path.join(BASE_DIR,'db')
</div>

 

服务器端:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import sys,os
import time
import socket
import hashlib
import pickle
import subprocess
import socketserver
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
from config import settings
 
 
new=settings.NEW_FILENAME
class Myserver(socketserver.BaseRequestHandler):
 
  def recv_file(self):
    '''
    文件传输
    :return:
    '''
    conn=self.request
    a=str(conn.recv(1024),encoding='utf-8')
    file_size,file_name=a.split(',')
    new_file_name=os.path.join(new,file_name)
    if file_name in new:      #检测文件是否已存在,涉及断点续传
      has_recv=os.stat(new).st_size #计算临时文件大小
      conn.sendall(bytes(has_recv,encoding='utf-8'))
      with open(new_file_name,'ab') as f: #追加模式
        while has_recv<=int(file_size):
          data=conn.recv(1024)
          f.write(data)
          has_recv+=len(data)
    else:
      has_recv=0
      conn.sendall(bytes('s',encoding='utf-8')) # 客户端收到字符串s,从0开始发送
      with open(new_file_name,'wb') as f:
        while has_recv<=int(file_size):
          data=conn.recv(1024)
          f.write(data)
          has_recv+=len(data)
 
  def command(self):
    '''
    执行命令
    :return:
    '''
    conn=self.request
    a=conn.recv(1024)
    ret=str(a,encoding='utf-8')
    ret2 = subprocess.check_output(ret, shell=True)
    r=divmod(len(ret2),1024)
    s=r[0]+1     #客户端需要接收的次数
    conn.sendall(bytes(str(s),encoding='utf-8'))
    conn.recv(1024) #确认客户端收到需要接收的次数
 
    conn.sendall(ret2)
 
  def md5(self,pwd):
    '''
    对密码进行加密
    :param pwd: 密码
    :return:
    '''
    hash=hashlib.md5(bytes('xx7',encoding='utf-8'))
    hash.update(bytes(pwd,encoding='utf-8'))
    return hash.hexdigest()
 
 
  def login(self,usrname,pwd):
    '''
    登陆
    :param usrname: 用户名
    :param pwd: 密码
    :return:是否登陆成功
    '''
    conn=self.request
    s=pickle.load(open(settings.NAME_PWD,'rb'))
    if usrname in s:
       if s[usrname]==self.md5(pwd):    #和加密后的密码进行比较
        return True
       else:
        return False
    else:
      return False
 
 
  def regist(self,usrname,pwd):
    '''
    注册
    :param usrname: 用户名
    :param pwd: 密码
    :return:是否注册成功
    '''
 
    conn=self.request
    s=pickle.load(open(settings.NAME_PWD,'rb'))
    if usrname in s:
       return False
    else:
      s[usrname]=self.md5(pwd)
      mulu=os.path.join(settings.USER_FILE,usrname)
      os.makedirs(mulu,'a')
      pickle.dump(s,open(settings.NAME_PWD,'wb'))
      return True
 
  def before(self,usrname,pwd,ret):
    '''
    判断注册和登陆,并展示用户的详细目录信息,支持cd和ls命令
    :return:
    '''
    conn=self.request
    if ret=='1':
      r=self.login(usrname,pwd)
      if r:
        conn.sendall(bytes('y',encoding='utf-8'))
      else:
        conn.sendall(bytes('n',encoding='utf-8'))
    elif ret=='2':
      # print(usrname,pwd)
      r=self.regist(usrname,pwd)
      if r:
        conn.sendall(bytes('y',encoding='utf-8'))
      else:
        conn.sendall(bytes('n',encoding='utf-8'))
  def usr_file(self,usrname):
    '''
    展示用户的详细目录信息,支持cd和ls命令
    :param usrname: 用户名
    :return:
    '''
    conn=self.request
    conn.recv(1024)
    mulu=os.path.join(settings.USER_FILE,usrname)
    conn.sendall(bytes(mulu,encoding='utf-8'))
    while True:
      b=conn.recv(1024)
      ret=str(b,encoding='utf-8')
      try:
        a,b=ret.split(' ',1)
      except Exception as e:
        a=ret
      if a=='cd':
        if b=='..':
          mulu=os.path.dirname(mulu)
        else:
          mulu=os.path.join(mulu,b)
        conn.sendall(bytes(mulu,encoding='utf-8'))
      elif a=='ls':
        ls=os.listdir(mulu)
        print(ls)
        a=','.join(ls)
        conn.sendall(bytes(a,encoding='utf-8'))
      elif a=='q':
        break
 
 
  def handle(self):
    conn=self.request
    conn.sendall(bytes('welcome',encoding='utf-8'))
    b=conn.recv(1024)
    ret=str(b,encoding='utf-8')
    print(ret)
    conn.sendall(bytes('b ok',encoding='utf-8'))
    c=conn.recv(1024)
    r=str(c,encoding='utf-8')
    usrname,pwd=r.split(',')
    self.before(usrname,pwd,ret) #登陆或注册验证
    self.usr_file(usrname) #展示用户的详细目录信息,支持cd和ls命令
    while True:
      a=conn.recv(1024)
      conn.sendall(bytes('收到a',encoding='utf-8'))
      ret=str(a,encoding='utf-8')
      if ret=='1':
        self.recv_file()
        # conn.sendall(bytes('file ok',encoding='utf-8'))
      elif ret=='2':
        self.command()
      elif ret=='q':
        break
      else:
        pass
 
if __name__=='__main__':
  sever=socketserver.ThreadingTCPServer(('127.0.0.1',9999),Myserver)
  sever.serve_forever()
</div>

客户端:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import sys
import time
import os
import socket
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
from config import settings
 
 
 
def send_file(file_p
  


 

您可能想查找下面的文章:

  • python实现可以断点续传和并发的ftp程序
  • python实现可以断点续传和并发的ftp程序

相关文章

  • Python中MySQLdb和torndb模块对MySQL的断连问题处理
  • python清除字符串里非字母字符的方法
  • 在Python中使用CasperJS获取JS渲染生成的HTML内容的教程
  • Python socket网络编程TCP/IP服务器与客户端通信
  • 介绍Python的Django框架中的静态资源管理器django-pipeline
  • python使用pymysql实现操作mysql
  • Python简单获取自身外网IP的方法
  • Python中计算三角函数之cos()方法的使用简介
  • python网络编程之读取网站根目录实例
  • python实现在字符串中查找子字符串的方法

文章分类

  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell

最近更新的内容

    • Python转换HTML到Text纯文本的方法
    • Python控制多进程与多线程并发数总结
    • python实现根据月份和日期得到星座的方法
    • 详解python调度框架APScheduler使用
    • python实现爬虫下载漫画示例
    • Python中asyncore异步模块的用法及实现httpclient的实例
    • Python常见格式化字符串方法小结【百分号与format方法】
    • 从零学python系列之教你如何根据图片生成字符画
    • 跟老齐学Python之重回函数
    • 记录Django开发心得

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有