Python实现的FTP通信客户端与服务器端功能示例


Posted in Python onMarch 28, 2018

本文实例讲述了Python实现的FTP通信客户端与服务器端功能。分享给大家供大家参考,具体如下:

一 代码

1、服务端代码

import socket
import threading
import os
import struct
#用户账号、密码、主目录
#也可以把这些信息存放到数据库中
users = {'zhangsan':{'pwd':'zhangsan1234', 'home':r'c:\python 3.5'},
     'lisi':{'pwd':'lisi567', 'home':'c:\\'}}
def server(conn,addr, home):
  print('新客户端:'+str(addr))
  #进入当前用户主目录
  os.chdir(home)
  while True:
    data = conn.recv(100).decode().lower()
    #显示客户端输入的每一条命令
    print(data)
    #客户端退出
    if data in ('quit', 'q'):
      break
    #查看当前文件夹的文件列表
    elif data in ('list', 'ls', 'dir'):
      files = str(os.listdir(os.getcwd()))
      files = files.encode()
      conn.send(struct.pack('I', len(files)))
      conn.send(files)
    #切换至上一级目录
    elif ''.join(data.split()) == 'cd..':
      cwd = os.getcwd()
      newCwd = cwd[:cwd.rindex('\\')]
      #考虑根目录的情况
      if newCwd[-1] == ':':
        newCwd += '\\'
      #限定用户主目录
      if newCwd.lower().startswith(home):
        os.chdir(newCwd)
        conn.send(b'ok')
      else:
        conn.send(b'error')
    #查看当前目录
    elif data in ('cwd', 'cd'):
      conn.send(str(os.getcwd()).encode())
    elif data.startswith('cd '):
      #指定最大分隔次数,考虑目标文件夹带有空格的情况
      #只允许使用相对路径进行跳转
      data = data.split(maxsplit=1)
      if len(data) == 2 and os.path.isdir(data[1]) \
        and data[1]!=os.path.abspath(data[1]):
        os.chdir(data[1])
        conn.send(b'ok')
      else:
        conn.send(b'error')
    #下载文件
    elif data.startswith('get '):
      data = data.split(maxsplit=1)
      #检查文件是否存在
      if len(data) == 2 and os.path.isfile(data[1]):
        conn.send(b'ok')
        fp = open(data[1], 'rb')
        while True:
          content = fp.read(4096)
          #发送文件结束
          if not content:
            conn.send(b'overxxxx')
            break
          #发送文件内容
          conn.send(content)
          if conn.recv(10) == b'ok':
            continue
        fp.close()
      else:
        conn.send(b'no')
    #无效命令
    else:
      pass
  conn.close()
  print(str(addr)+'关闭连接')
#创建Socket,监听本地端口,等待客户端连接
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 10600))
sock.listen(5)
while True:
  conn, addr = sock.accept()
  #验证客户端输入的用户名和密码是否正确
  userId, userPwd = conn.recv(1024).decode().split(',')
  if userId in users and users[userId]['pwd'] == userPwd:
    conn.send(b'ok')
    #为每个客户端连接创建并启动一个线程,参数为连接、客户端地址、客户主目录
    home = users[userId]['home']
    t = threading.Thread(target=server, args=(conn,addr,home))
    t.daemon = True
    t.start()
  else:
    conn.send(b'error')

2、客户端代码

import socket
import sys
import re
import struct
import getpass
def main(serverIP):
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  sock.connect((serverIP, 10600))
  userId = input('请输入用户名:')
  #使用getpass模块的getpass()方法获取密码,不回显
  userPwd = getpass.getpass('请输入密码:')
  message = userId+','+userPwd
  sock.send(message.encode())
  login = sock.recv(100)
  #验证是否登录成功
  if login == b'error':
    print('用户名或密码错误')
    return
  #整数编码大小
  intSize = struct.calcsize('I')
  while True:
    #接收客户端命令,其中##>是提示符
    command = input('##> ').lower().strip()
    #没有输入任何有效字符,提前进入下一次循环,等待用户继续输入
    if not command:
      continue
    #向服务端发送命令
    command = ' '.join(command.split())
    sock.send(command.encode())
    #退出
    if command in ('quit', 'q'):
      break
    #查看文件列表
    elif command in ('list', 'ls', 'dir'):
      loc_size = struct.unpack('I', sock.recv(intSize))[0]
      files = eval(sock.recv(loc_size).decode())
      for item in files:
        print(item)
    #切换至上一级目录
    elif ''.join(command.split()) == 'cd..':
      print(sock.recv(100).decode())
    #查看当前工作目录
    elif command in ('cwd', 'cd'):
      print(sock.recv(1024).decode())
    #切换至子文件夹
    elif command.startswith('cd '):
      print(sock.recv(100).decode())
    #从服务器下载文件
    elif command.startswith('get '):
      isFileExist = sock.recv(20)
      #文件不存在
      if isFileExist != b'ok':
        print('error')
      #文件存在,开始下载
      else:
        print('downloading.', end='')
        fp = open(command.split()[1], 'wb')
        while True:
          print('.', end='')
          data = sock.recv(4096)
          if data == b'overxxxx':
            break
          fp.write(data)
          sock.send(b'ok')
        fp.close()
        print('ok')
    #无效命令
    else:
      print('无效命令')
  sock.close()
if __name__ == '__main__':
  if len(sys.argv) != 2:
    print('Usage:{0} serverIPAddress'.format(sys.argv[0]))
    exit()
  serverIP = sys.argv[1]
  if re.match(r'^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$', serverIP):
    main(serverIP)
  else:
    print('服务器地址不合法')
    exit()

二 运行结果

客户端运行结果

Python实现的FTP通信客户端与服务器端功能示例

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python进程通信之匿名管道实例讲解
Apr 11 Python
基于scrapy实现的简单蜘蛛采集程序
Apr 17 Python
多个应用共存的Django配置方法
May 30 Python
python2和python3的输入和输出区别介绍
Nov 20 Python
python通过ffmgep从视频中抽帧的方法
Dec 05 Python
Python实现二叉树前序、中序、后序及层次遍历示例代码
May 18 Python
Python 求数组局部最大值的实例
Nov 26 Python
python 统计文件中的字符串数目示例
Dec 24 Python
Python 批量读取文件中指定字符的实现
Mar 06 Python
Django配置跨域并开发测试接口
Nov 04 Python
Python列表元素删除和remove()方法详解
Jan 04 Python
Python源码解析之List
May 21 Python
Python实现发送与接收邮件的方法详解
Mar 28 #Python
Python实现线程状态监测简单示例
Mar 28 #Python
python实现朴素贝叶斯分类器
Mar 28 #Python
详解Python中where()函数的用法
Mar 27 #Python
Django基于ORM操作数据库的方法详解
Mar 27 #Python
利用Python批量提取Win10锁屏壁纸实战教程
Mar 27 #Python
Django学习笔记之ORM基础教程
Mar 27 #Python
You might like
分页显示Oracle数据库记录的类之一
2006/10/09 PHP
PHP中的按位与和按位或操作示例
2014/01/27 PHP
php curl操作API接口类完整示例
2019/05/21 PHP
javascript 验证日期的函数
2010/03/18 Javascript
js 编程笔记 无名函数
2011/06/28 Javascript
c#和Javascript操作同一json对象的实现代码
2012/01/17 Javascript
jQuery动画效果-slideUp slideDown上下滑动示例代码
2013/08/28 Javascript
多种方法判断Javascript对象是否存在
2013/09/22 Javascript
JavaScript中String.match()方法的使用详解
2015/06/06 Javascript
JS正则表达式比较常见用法
2016/01/26 Javascript
bootstrap学习笔记之初识bootstrap
2016/06/21 Javascript
纯JavaScript 实现flappy bird小游戏实例代码
2016/09/27 Javascript
require.js+vue开发微信上传图片组件
2016/10/27 Javascript
实例解析jQuery中如何取消后续执行内容
2016/12/01 Javascript
简单实现jQuery多选框功能
2017/01/09 Javascript
webgl实现物体描边效果的方法介绍
2019/11/27 Javascript
原生JavaScript实现贪吃蛇游戏
2020/11/04 Javascript
详解Python自建logging模块
2018/01/29 Python
Python Logging 日志记录入门学习
2018/06/02 Python
对python cv2批量灰度图片并保存的实例讲解
2018/11/09 Python
Python 复平面绘图实例
2019/11/21 Python
Python的赋值、深拷贝与浅拷贝的区别详解
2020/02/12 Python
python如何调用java类
2020/07/05 Python
Ubuntu 20.04安装Pycharm2020.2及锁定到任务栏的问题(小白级操作)
2020/10/29 Python
Python使用grequests并发发送请求的示例
2020/11/05 Python
传统HTML页面实现模块化加载的方法
2018/10/15 HTML / CSS
学生党员思想汇报
2013/12/28 职场文书
学习决心书
2014/03/11 职场文书
政风行风整改方案
2014/10/25 职场文书
2014年学前班工作总结
2014/12/08 职场文书
辞职书格式样本
2015/02/26 职场文书
入党团支部推荐意见
2015/06/02 职场文书
自荐信范文
2019/05/20 职场文书
导游词之湖州-太湖
2019/10/11 职场文书
Python机器学习之决策树和随机森林
2021/07/15 Javascript
MySQL范围查询优化的场景实例详解
2022/06/10 MySQL