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在多玩图片上下载妹子图的实现代码
Aug 13 Python
Python使用MySQLdb for Python操作数据库教程
Oct 11 Python
python语言使用技巧分享
May 31 Python
使用python爬虫实现网络股票信息爬取的demo
Jan 05 Python
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
Feb 10 Python
Python正则表达式实现简易计算器功能示例
May 07 Python
Python三元运算与lambda表达式实例解析
Nov 30 Python
keras获得model中某一层的某一个Tensor的输出维度教程
Jan 24 Python
python函数调用,循环,列表复制实例
May 03 Python
python处理写入数据代码讲解
Oct 22 Python
Python pyecharts绘制条形图详解
Apr 02 Python
Python+Pillow+Pytesseract实现验证码识别
May 11 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 Ajax中文乱码问题解决方法
2009/02/27 PHP
PHP中绘制图像的一些函数总结
2014/11/19 PHP
php中静态类与静态变量用法的区别分析
2015/01/15 PHP
thinkPHP批量删除的实现方法分析
2016/11/09 PHP
PHP基于方差和标准差计算学生成绩的稳定性示例
2017/07/04 PHP
PHP文件打开关闭及读写操作示例解析
2020/08/06 PHP
模拟jQuery ajax服务器端与客户端通信的代码
2011/03/28 Javascript
qTip2 精致的基于jQuery提示信息插件
2012/02/17 Javascript
Javascript实现DIV滚动自动滚动到底部的代码
2012/03/01 Javascript
JQuery实现用户名无刷新验证的小例子
2013/03/22 Javascript
jquery动态加载js三种方法实例
2013/08/03 Javascript
快速解决jQuery与其他库冲突的方法介绍
2014/01/02 Javascript
javaScript年份下拉列表框内容为当前年份及前后50年
2014/05/28 Javascript
Javascript单例模式的介绍和实例
2016/10/08 Javascript
Vue.js仿Metronic高级表格(一)静态设计
2017/04/17 Javascript
Popup弹出框添加数据实现方法
2017/10/27 Javascript
Node.js 利用cheerio制作简单的网页爬虫示例
2018/03/01 Javascript
ES6入门教程之变量的解构赋值详解
2019/04/13 Javascript
利用JavaScript将Excel转换为JSON示例代码
2019/06/14 Javascript
vue中echarts图表大小适应窗口大小且不需要刷新案例
2020/07/19 Javascript
python实现的阳历转阴历(农历)算法
2014/04/25 Python
python快速查找算法应用实例
2014/09/26 Python
Python中time模块与datetime模块在使用中的不同之处
2015/11/24 Python
使用Python进行中文繁简转换的实现代码
2019/10/18 Python
解决Pycharm的项目目录突然消失的问题
2020/01/20 Python
超级实用的8个Python列表技巧
2020/08/24 Python
Hawes & Curtis官网:英国经典品牌
2019/07/27 全球购物
培训专员岗位职责
2014/02/26 职场文书
员工工作表现评语
2014/04/26 职场文书
我读书我快乐演讲稿
2014/05/07 职场文书
学生吸烟检讨书
2014/09/14 职场文书
2014年人事行政工作总结
2014/12/03 职场文书
2015年妇幼卫生工作总结
2015/05/23 职场文书
投诉信范文
2015/07/02 职场文书
争做文明公民倡议书
2019/06/24 职场文书
SpringDataJPA在Entity中常用的注解介绍
2021/12/06 Java/Android