SoFunction
Updated on 2024-11-12

python implementation of ftp program can be intermittent transfer and concurrent

preamble

When downloading a file, you are most afraid of being disconnected in the middle and not being able to download the complete file successfully. With Breakpoint Transfer, you can pick up the file where it left off without having to re-download it. This feature is very useful for downloading larger files. So this article will share with you how to use python to implement a ftp program that can be disconnected and concurrent.

I. Requirements

1、User md5 authentication

2、Support multiple users to log in at the same time (concurrent)

3, enter the user's command line mode, support cd switch directory, ls view directory subfiles

4. Execute the command (ipconfig)

5. Transmission of documents:

a. Support breakpoint continuous transmission

b. Progress bar displayed during transmission

II. Thoughts

1. Client user login and registration:

a. The client only provides a user name and password, choosing to log in or register.

b. The server side registers and writes the encrypted password into the file, and finally returns to the client whether the login or registration is successful.

and cd commands

a. The client enters the command, the server side processes it and returns it to the client.

3. Execute the order:

a. The client sends the command to be executed

b, the server side to execute the command, and return to the client needs to receive the number of times the command s = r [0] +1, where r = divmod (the total length of the results, 1024)

c. Number of times the client has received it, telling the server that it has received it

d. The server sends the result of the execution, and the client receives the result in a for loop.

4. Sending documents:

a. The client inputs the file path (the beta path is:), sends the file name and file size

b, the server detects whether the specified directory contains the file, if not, return to the client string s, that is, from the beginning to send start, has_recv = 0
If there is, i.e., you need to break the upload, return to the client how many has_recv have been uploaded

c. The client receives the return value and searches to the location of has_recv, sends and receives in a loop, and prints the current progress until the transmission is complete.

Note: This program can cycle through user-selected file transfers and execution commands

III. Codes

Configuration file:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
 
BASE_DIR = ((__file__)) The upper directory of the # configuration file
NEW_FILENAME=(BASE_DIR,'view')       # New file directory
NAME_PWD=(BASE_DIR,'db','name_pwd')    # Username and password directory
USER_FILE=(BASE_DIR,'db')

 

Server-side:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import sys,os
import time
import socket
import hashlib
import pickle
import subprocess
import socketserver
(((__file__)))
from config import settings
 
 
new=settings.NEW_FILENAME
class Myserver():
 
  def recv_file(self):
    '''
    File Transfer
    :return.
    '''
    conn=
    a=str((1024),encoding='utf-8')
    file_size,file_name=(',')
    new_file_name=(new,file_name)
    if file_name in new:      #Detect if a file already exists, involves broken transfers
      has_recv=(new).st_size # Calculate temporary file size
      (bytes(has_recv,encoding='utf-8'))
      with open(new_file_name,'ab') as f: #Additional mode
        while has_recv<=int(file_size):
          data=(1024)
          (data)
          has_recv+=len(data)
    else:
      has_recv=0
      (bytes('s',encoding='utf-8')) # Client receives string s, sends from 0
      with open(new_file_name,'wb') as f:
        while has_recv<=int(file_size):
          data=(1024)
          (data)
          has_recv+=len(data)
 
  def command(self):
    '''
    Execute the command
    :return.
    '''
    conn=
    a=(1024)
    ret=str(a,encoding='utf-8')
    ret2 = subprocess.check_output(ret, shell=True)
    r=divmod(len(ret2),1024)
    s=r[0]+1     # of times the client needs to receive
    (bytes(str(s),encoding='utf-8'))
    (1024) # of acknowledgements received by the client that need to be received
 
    (ret2)
 
  def md5(self,pwd):
    '''
    Encrypt the password
    :param pwd: password
    :return.
    '''
    hash=hashlib.md5(bytes('xx7',encoding='utf-8'))
    (bytes(pwd,encoding='utf-8'))
    return ()
 
 
  def login(self,usrname,pwd):
    '''
    Login
    :param usrname: username
    :param pwd: password
    :return:Whether the login succeeded or not
    '''
    conn=
    s=(open(settings.NAME_PWD,'rb'))
    if usrname in s:
       if s[usrname]==self.md5(pwd):    # Compare with encrypted passwords
        return True
       else:
        return False
    else:
      return False
 
 
  def regist(self,usrname,pwd):
    '''
    Register
    :param usrname: username
    :param pwd: password
    :return:Whether registration was successful or not
    '''
 
    conn=
    s=(open(settings.NAME_PWD,'rb'))
    if usrname in s:
       return False
    else:
      s[usrname]=self.md5(pwd)
      mulu=(settings.USER_FILE,usrname)
      (mulu,'a')
      (s,open(settings.NAME_PWD,'wb'))
      return True
 
  def before(self,usrname,pwd,ret):
    '''
    Determine registration and login, and display the user's detailed directory information, support cd and ls commands
    :return.
    '''
    conn=
    if ret=='1':
      r=(usrname,pwd)
      if r:
        (bytes('y',encoding='utf-8'))
      else:
        (bytes('n',encoding='utf-8'))
    elif ret=='2':
      # print(usrname,pwd)
      r=(usrname,pwd)
      if r:
        (bytes('y',encoding='utf-8'))
      else:
        (bytes('n',encoding='utf-8'))
  def usr_file(self,usrname):
    '''
    Show user's detailed directory information, support cd and ls commands
    :param usrname: username
    :return.
    '''
    conn=
    (1024)
    mulu=(settings.USER_FILE,usrname)
    (bytes(mulu,encoding='utf-8'))
    while True:
      b=(1024)
      ret=str(b,encoding='utf-8')
      try:
        a,b=(' ',1)
      except Exception as e:
        a=ret
      if a=='cd':
        if b=='..':
          mulu=(mulu)
        else:
          mulu=(mulu,b)
        (bytes(mulu,encoding='utf-8'))
      elif a=='ls':
        ls=(mulu)
        print(ls)
        a=','.join(ls)
        (bytes(a,encoding='utf-8'))
      elif a=='q':
        break
 
 
  def handle(self):
    conn=
    (bytes('welcome',encoding='utf-8'))
    b=(1024)
    ret=str(b,encoding='utf-8')
    print(ret)
    (bytes('b ok',encoding='utf-8'))
    c=(1024)
    r=str(c,encoding='utf-8')
    usrname,pwd=(',')
    (usrname,pwd,ret) #Login or Registration Verification
    self.usr_file(usrname) # Show user's detailed directory information, support cd and ls commands
    while True:
      a=(1024)
      (bytes('Received a',encoding='utf-8'))
      ret=str(a,encoding='utf-8')
      if ret=='1':
        self.recv_file()
        # (bytes('file ok',encoding='utf-8'))
      elif ret=='2':
        ()
      elif ret=='q':
        break
      else:
        pass
 
if __name__=='__main__':
  sever=(('127.0.0.1',9999),Myserver)
  sever.serve_forever()

Client:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import sys
import time
import os
import socket
(((__file__)))
from config import settings
 
 
 
def send_file(file_path):
  '''
  Send file
  :param file_name:file name
  :return.
  '''
  size=(file_path).st_size
  file_name=(file_path)
  (bytes(str(size)+','+file_name,encoding='utf-8')) # Send file size and file name
  ret=(1024)  # Receive how much has been passed
  r=str(ret,encoding='utf-8')
  if r=='s': # File does not exist, pass it from the beginning
    has_send=0
  else:  # file exists
    has_send=int(r)
 
  with open(file_path,'rb') as f:
    (has_send) #Locate to a location that has already been transmitted
    while has_send<size:
      data=(1024)
      (data)
      has_send+=len(data)
      ('\r') # Empty the contents of the file
      (0.2)
      ('Sent %s%%|%s' %(int(has_send/size*100),(round(has_send/size*40)*'★')))
      ()  #Forced swipe out of memory
    print("Upload successful\n")
 
def command(command_name):
  '''
  Execute the command
  :param command_name.
  :return.
  '''
  (bytes(command_name,encoding='utf-8'))
  ret=(1024) # of times a receive command needs to be received
  (bytes('Number of times received',encoding='utf-8'))
  r=str(ret,encoding='utf-8')
  for i in range(int(r)): # need to receive int(r) a total of times
    ret=(1024) # Waiting for the client to send
    r=str(ret,encoding='GBK')
    print(r)
 
def login(usrname,pwd):
  '''
  Login
  :param usrname:username
  :param pwd:password
  :return:Successful login or not
  '''
  (bytes(usrname+','+pwd,encoding='utf-8'))
  ret=(1024)
  r=str(ret,encoding='utf-8')
  if r=='y':
    return 1
  else:
    return 0
 
def regist(usrname,pwd):
  '''
  Register
  :param usrname:username
  :param pwd:password
  :return:Whether registration was successful or not
  '''
  (bytes(usrname+','+pwd,encoding='utf-8'))
  ret=(1024)
  r=str(ret,encoding='utf-8')
  if r=='y':
    return 1
  else:
    return 0
def before(usrname,pwd):
  '''
  Select login or register, show user's detailed directory information, support cd and ls commands
  :return.
  '''
  a=input('Please select 1.Login 2.Register')
  (bytes(a,encoding='utf-8'))
  (1024)
  if a=='1':
    ret=login(usrname,pwd)
    if ret:
      print('Login successful')
      return 1
    else:
      print('Username or password error')
      return 0
  elif a=='2':
    ret=regist(usrname,pwd)
    if ret:
      print('Registration Successful')
      return 1
    else:
      print('User name already exists')
      return 0
def usr_file(usrname):
  (bytes('Print user file path',encoding='utf-8'))
  ret=(1024) # Waiting for the client to send
  r=str(ret,encoding='utf-8')
  print(r)
  while True:
    a=input('Type cd to switch directories, ls to view directory details, q to exit>:')
 
    (bytes(a,encoding='utf-8'))
    if a=='q':
      break
    else:
      ret=(1024) # Waiting for the client to send
      r=str(ret,encoding='utf-8')
      if len(r)==1:# Determine if it's a cd result or an ls result (ls with only one subdirectory can also be printed directly)
        print(r)
      else:
        li=(',')
        for i in li:
          print(i) # Print every subdirectory
 
def main(usrname,pwd):
  ret=(1024) # Waiting for the client to send
  r=str(ret,encoding='utf-8')
  print(r)
  result=before(usrname,pwd)#Login or Register
  if result:
    usr_file(usrname)
    while True:
      a=input('Please choose 1. to pass a file 2. to execute a command q to exit:')
      (bytes(str(a),encoding='utf-8'))
      ret=(1024) # Confirmation of receipta
      r=str(ret,encoding='utf-8')
      print(r)
      if a=='1':
        b=input('Please enter the file path (beta path is:):')
        # b=''
        if (b):
          send_file(b)
          (bytes('hhe',encoding='utf-8'))
          # (1024)
      elif a=='2':
        b=input('Please enter command:')
        command(b)
      elif a=='q':
        break
      else:
        print('Input error')
 
  ()
 
if __name__ == '__main__':
  obj=() # Create a client socket object
  (('127.0.0.1',9999))
  usrname=input('Please enter a user name')
  pwd=input('Please enter your password')
  main(usrname,pwd)

summarize

Above is the python implementation can be intermittent and concurrent ftp program all, the article describes the details, I hope you learn or use python to bring some help.