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计算最小优先级队列代码分享
Dec 18 Python
python实现的简单猜数字游戏
Apr 04 Python
Python探索之自定义实现线程池
Oct 27 Python
pycharm下查看python的变量类型和变量内容的方法
Jun 26 Python
利用django-suit模板添加自定义的菜单、页面及设置访问权限
Jul 13 Python
python检测IP地址变化并触发事件
Dec 26 Python
在django admin中添加自定义视图的例子
Jul 26 Python
Django shell调试models输出的SQL语句方法
Aug 29 Python
Django框架安装及项目创建过程解析
Sep 14 Python
python自动化测试三部曲之request+django实现接口测试
Oct 07 Python
python 三种方法实现对Excel表格的读写
Nov 19 Python
python 获取谷歌浏览器保存的密码
Jan 06 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
thinkphp5 加载静态资源路径与常量的方法
2017/12/24 PHP
php中文语义分析实现方法示例
2019/09/28 PHP
文本加密解密
2006/06/23 Javascript
Javascript的一种模块模式
2008/03/22 Javascript
基于jQuery UI CSS Framework开发Widget的经验
2010/08/21 Javascript
Jquery实现弹出层分享微博插件具备动画效果
2013/04/03 Javascript
JavaScript中伪协议 javascript:使用探讨
2014/07/18 Javascript
JavaScript实现列表分页功能特效
2015/05/15 Javascript
轻松实现javascript数据双向绑定
2015/11/11 Javascript
JavaScript操作 url 中 search 部分方法函数
2016/06/15 Javascript
Move.js入门
2017/02/08 Javascript
Bootstrap媒体对象学习使用
2017/03/07 Javascript
Vue 父子组件、组件间通信
2017/03/08 Javascript
jQuery Plupload上传插件的使用
2017/04/19 jQuery
nodejs实现简单的gulp打包
2017/12/21 NodeJs
详解如何更好的使用module vuex
2019/03/27 Javascript
js实现无缝轮播图效果
2020/03/09 Javascript
寻找网站后台地址的python脚本
2014/09/01 Python
Python实现配置文件备份的方法
2015/07/30 Python
python机器学习实战之最近邻kNN分类器
2017/12/20 Python
python web.py开发httpserver解决跨域问题实例解析
2018/02/12 Python
Django中自定义模型管理器(Manager)及方法
2019/09/23 Python
Python安装依赖(包)模块方法详解
2020/02/14 Python
Django模板之基本的 for 循环 和 List内容的显示方式
2020/03/31 Python
Pycharm中安装Pygal并使用Pygal模拟掷骰子(推荐)
2020/04/08 Python
CSS3实现自定义Checkbox特效实例代码
2017/04/24 HTML / CSS
HTML5实现多张图片上传功能
2016/03/11 HTML / CSS
凯特·丝蓓英国官网:Kate Spade英国
2016/11/07 全球购物
Ralph Lauren法国官网:美国高品味时装品牌
2017/12/08 全球购物
What is view? why do we have view?
2012/06/22 面试题
求职信模板怎么做
2014/01/26 职场文书
国际贸易求职信
2014/07/05 职场文书
乡镇四风对照检查材料
2014/08/31 职场文书
党员干部形式主义个人整改措施
2014/09/17 职场文书
银行求职信模板
2015/03/20 职场文书
经典格言警句:没有热忱,世间便无进步
2019/11/13 职场文书