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实现sublime3的less编译插件示例
Apr 27 Python
Python中的多重装饰器
Apr 11 Python
使用Python设计一个代码统计工具
Apr 04 Python
python使用Matplotlib绘制分段函数
Sep 25 Python
python使用插值法画出平滑曲线
Dec 15 Python
Python实现的调用C语言函数功能简单实例
Mar 13 Python
Python基本数据结构之字典类型dict用法分析
Jun 08 Python
python里 super类的工作原理详解
Jun 19 Python
python自动化工具之pywinauto实例详解
Aug 26 Python
Python常用库大全及简要说明
Jan 17 Python
python json load json 数据后出现乱序的解决方案
Feb 27 Python
python 装饰器的使用示例
Oct 10 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
php数组函数序列之ksort()对数组的元素键名进行升序排序,保持索引关系
2011/11/02 PHP
PHP输入流php://input介绍
2012/09/18 PHP
php中DOMElement操作xml文档实例演示
2013/03/26 PHP
zf框架的校验器InArray使用示例
2014/03/13 PHP
PHP中使用json数据格式定义字面量对象的方法
2014/08/20 PHP
PHP浮点数精度问题汇总
2015/05/13 PHP
Javascript 网页黑白效果实现代码(兼容IE/FF等)
2010/04/23 Javascript
DOM事件探秘篇
2017/02/15 Javascript
Node.js操作redis实现添加查询功能
2017/05/25 Javascript
JS实现弹出下载对话框及常见文件类型的下载
2017/07/13 Javascript
nodejs body-parser 解析post数据实例
2017/07/26 NodeJs
vue实现百度搜索功能
2020/12/28 Javascript
vue实现页面切换滑动效果
2020/06/29 Javascript
Vue-cli4 配置 element-ui 按需引入操作
2020/09/11 Javascript
[05:03]显微镜下的DOTA2第十期——Ti3豪之超神幽鬼
2014/06/23 DOTA
从零学Python之引用和类属性的初步理解
2014/05/15 Python
Python单元测试框架unittest使用方法讲解
2015/04/13 Python
使用Python发送各种形式的邮件的方法汇总
2015/11/09 Python
Python中单、双下划线的区别总结
2017/12/01 Python
python 判断矩阵中每行非零个数的方法
2019/01/26 Python
对python中list的拷贝与numpy的array的拷贝详解
2019/01/29 Python
Python实现的矩阵转置与矩阵相乘运算示例
2019/03/26 Python
零基础使用Python读写处理Excel表格的方法
2019/05/02 Python
python3发送邮件需要经过代理服务器的示例代码
2019/07/25 Python
pygame用blit()实现动画效果的示例代码
2020/05/28 Python
浅谈opencv自动光学检测、目标分割和检测(连通区域和findContours)
2020/06/04 Python
利用Python实现Excel的文件间的数据匹配功能
2020/06/16 Python
零基础学Python之前需要学c语言吗
2020/07/21 Python
旅游管理专业生自荐信范文
2014/01/02 职场文书
建筑个人求职信范文
2014/01/25 职场文书
建议书标准格式
2014/03/12 职场文书
责任胜于能力演讲稿
2014/05/20 职场文书
自愿离婚协议书2015
2015/01/26 职场文书
投诉信范文
2015/07/02 职场文书
高三教师工作总结2015
2015/07/21 职场文书
实用干货:敬酒词大全,帮你应付各种场合
2019/11/21 职场文书