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 pdb调试方法分享
Jan 21 Python
在Python中用has_key()方法查找键是否存在的教程
May 21 Python
Python基于identicon库创建类似Github上用的头像功能
Sep 25 Python
Pandas读取MySQL数据到DataFrame的方法
Jul 25 Python
Python实现的大数据分析操作系统日志功能示例
Feb 11 Python
Python爬虫运用正则表达式的方法和优缺点
Aug 25 Python
python tkinter控件布局项目实例
Nov 04 Python
python 动态绘制爱心的示例
Sep 27 Python
python 利用opencv实现图像网络传输
Nov 12 Python
python 通过exifread读取照片信息
Dec 24 Python
python3 实现mysql数据库连接池的示例代码
Apr 17 Python
Python绘制散乱的点构成的图的方法
Apr 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
php中echo()和print()、require()和include()等易混淆函数的区别
2012/02/22 PHP
PHP数据库万能引擎类adodb配置使用以及实例集锦
2014/06/12 PHP
PHP中16个高危函数整理
2019/09/19 PHP
Prototype使用指南之base.js
2007/01/10 Javascript
jquery获得下拉框值的代码
2011/08/13 Javascript
jQuery中siblings()方法用法实例
2015/01/08 Javascript
Javascript核心读书有感之表达式和运算符
2015/02/11 Javascript
jQuery团购倒计时特效实现方法
2015/05/07 Javascript
JavaScript电子时钟倒计时第二款
2016/01/10 Javascript
JavaScript+html5 canvas绘制渐变区域完整实例
2016/01/26 Javascript
Bootstrap登陆注册页面开发教程
2016/07/12 Javascript
Google 地图获取API Key详细教程
2016/08/06 Javascript
JavaScript表单验证实现代码
2017/05/22 Javascript
原生js FileReader对象实现图片上传本地预览效果
2020/03/27 Javascript
纯html+css+javascript实现楼层跳跃式的页面布局(实例代码)
2017/10/25 Javascript
web前端页面生成exe可执行文件的方法
2018/02/08 Javascript
vue.js实现简单的计算器功能
2020/02/22 Javascript
javascript设计模式 ? 观察者模式原理与用法实例分析
2020/04/22 Javascript
在Python的Django框架中实现Hacker News的一些功能
2015/04/17 Python
Python 3.x 新特性及10大变化
2015/06/12 Python
Python做简单的字符串匹配详解
2017/03/21 Python
python实现微信定时每天和女友发送消息
2019/04/29 Python
python实现读取类别频数数据画水平条形图案例
2020/04/24 Python
Python读取JSON数据操作实例解析
2020/05/18 Python
使用anaconda安装pytorch的实现步骤
2020/09/03 Python
python 如何使用find和find_all爬虫、找文本的实现
2020/10/16 Python
HTML5之SVG 2D入门10—滤镜的定义及使用
2013/01/30 HTML / CSS
Weekendesk意大利:探索多种引人入胜的周末主题
2016/10/14 全球购物
联想韩国官网:Lenovo Korea
2018/05/10 全球购物
GoDaddy英国:全球排名第一的域名注册商
2018/06/08 全球购物
中国跨镜手机配件批发在线商店:TVC-Mall
2019/08/20 全球购物
简历自我评价模版
2014/01/31 职场文书
研发工程师岗位职责
2014/04/28 职场文书
《7的乘法口诀》教学反思
2016/02/18 职场文书
诗词赏析-(浣溪沙)
2019/08/13 职场文书
python 命令行传参方法总结
2021/05/25 Python