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脚本使得web页面上的代码高亮显示
Apr 24 Python
新手如何快速入门Python(菜鸟必看篇)
Jun 10 Python
Python3学习笔记之列表方法示例详解
Oct 06 Python
Python BS4库的安装与使用详解
Aug 08 Python
深入浅析Python获取对象信息的函数type()、isinstance()、dir()
Sep 17 Python
Python3从零开始搭建一个语音对话机器人的实现
Aug 23 Python
python基于K-means聚类算法的图像分割
Oct 30 Python
Python爬虫解析网页的4种方式实例及原理解析
Dec 30 Python
python中format函数如何使用
Jun 22 Python
详解用Python爬虫获取百度企业信用中企业基本信息
Jul 02 Python
Python collections.deque双边队列原理详解
Oct 05 Python
python 写一个水果忍者游戏
Jan 13 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中的HashTable结构详解
2013/06/13 PHP
PHP编写学校网站上新生注册登陆程序的实例分享
2016/03/21 PHP
php使用FFmpeg接口获取视频的播放时长、码率、缩略图以及创建时间
2016/11/07 PHP
thinkPHP5.0框架整体架构总览【应用,模块,MVC,驱动,行为,命名空间等】
2017/03/25 PHP
PHP PDO和消息队列的个人理解与应用实例分析
2019/11/25 PHP
xss文件页面内容读取(解决)
2010/11/28 Javascript
javascript 判断字符串是否包含某字符串及indexOf使用示例
2013/10/18 Javascript
jquery ajax对特殊字符进行转义防止js注入使用示例
2013/11/21 Javascript
通过隐藏iframe实现文件下载的js方法介绍
2014/02/26 Javascript
Document.location.href和.replace的区别示例介绍
2014/03/04 Javascript
把文本中的URL地址转换为可点击链接的JavaScript、PHP自定义函数
2014/07/29 Javascript
js仿土豆网带缩略图的焦点图片切换效果实现方法
2015/02/23 Javascript
JavaScript中使用Math.PI圆周率属性的方法
2015/06/14 Javascript
jQuery实现带幻灯的tab滑动切换风格菜单代码
2015/08/27 Javascript
javascript图片切换综合实例(循环切换、顺序切换)
2016/01/13 Javascript
javascript实现简单计算器效果【推荐】
2016/04/19 Javascript
如何制作幻灯片(代码分享)
2017/01/06 Javascript
Vuex简单入门
2017/04/19 Javascript
Bootstrap组件之下拉菜单,多级菜单及按钮布局方法实例
2017/05/25 Javascript
nodejs实现超简单生成二维码的方法
2018/03/17 NodeJs
vue实现移动端触屏拖拽功能
2020/08/21 Javascript
python实现从网络下载文件并获得文件大小及类型的方法
2015/04/28 Python
在SAE上部署Python的Django框架的一些问题汇总
2015/05/30 Python
图解Python变量与赋值
2018/04/03 Python
Python 实现使用dict 创建二维数据、DataFrame
2018/04/13 Python
在Python中调用Ping命令,批量IP的方法
2019/01/26 Python
python GUI库图形界面开发之PyQt5表格控件QTableView详细使用方法与实例
2020/03/01 Python
python程序输出无内容的解决方式
2020/04/09 Python
美国市场上最实惠的送餐服务:Dinnerly
2018/03/18 全球购物
澳大利亚Rockwear官网:女子瑜伽、健身和运动服
2021/01/26 全球购物
人力资源行政经理自我评价
2013/10/23 职场文书
12.4法制宣传日活动总结
2014/08/26 职场文书
2015年新学期寄语
2015/02/26 职场文书
Nginx同一个域名配置多个项目的实现方法
2021/03/31 Servers
为什么不建议在go项目中使用init()
2021/04/12 Golang
Python编解码问题及文本文件处理方法详解
2021/06/20 Python