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 19 Python
跟老齐学Python之玩转字符串(3)
Sep 14 Python
python with提前退出遇到的坑与解决方案
Jan 05 Python
解决python3爬虫无法显示中文的问题
Apr 12 Python
pytorch 把MNIST数据集转换成图片和txt的方法
May 20 Python
Python如何实现在字符串里嵌入双引号或者单引号
Mar 02 Python
简单了解Python变量作用域正确使用方法
Jun 12 Python
python使用隐式循环快速求和的实现示例
Sep 11 Python
Django xadmin安装及使用详解
Oct 26 Python
如何在Python中创建二叉树
Mar 30 Python
Python进度条的使用
May 17 Python
python中使用 unittest.TestCase单元测试的用例详解
Aug 30 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
网页游戏开发入门教程三(简单程序应用)
2009/11/02 PHP
php文件上传表单摘自drupal的代码
2011/02/15 PHP
详解Window7 下开发php扩展
2015/12/31 PHP
php调用自己java程序的方法详解
2016/05/13 PHP
PHP之header函数详解
2021/03/02 PHP
通过JAVASCRIPT读取ASP设定的COOKIE
2007/02/15 Javascript
传递参数的标准方法(jQuery.ajax)
2008/11/19 Javascript
IE下写xml文件的两种方式(fso/saveAs)
2013/08/05 Javascript
使用phantomjs进行网页抓取的实现代码
2014/09/29 Javascript
谈一谈javascript闭包
2016/01/28 Javascript
Vue.js每天必学之过渡与动画
2016/09/06 Javascript
jQuery设置Easyui校验规则(推荐)
2016/11/21 Javascript
Javascript中for循环语句的几种写法总结对比
2017/01/23 Javascript
js date 格式化
2017/02/15 Javascript
微信小程序 wx.login解密出现乱码的问题解决办法
2017/03/10 Javascript
jquery+ajax实现省市区三级联动 (封装和不封装两种方式)
2017/05/15 jQuery
基于substring()和substr()的使用以及区别(实例讲解)
2017/12/28 Javascript
vue-lazyload图片延迟加载插件的实例讲解
2018/02/09 Javascript
nodejs实现解析xml字符串为对象的方法示例
2018/03/14 NodeJs
vue源码中的检测方法的实现
2019/09/26 Javascript
[00:10]DOTA2全国高校联赛速递
2018/05/30 DOTA
如何运行Python程序的方法
2013/04/21 Python
Python3用tkinter和PIL实现看图工具
2018/06/21 Python
Django contenttypes 框架详解(小结)
2018/08/13 Python
css3 给页面加个半圆形导航条主要利用旋转和倾斜样式
2014/02/10 HTML / CSS
基于HTML5新特性Mutation Observer实现编辑器的撤销和回退操作
2016/01/11 HTML / CSS
Haggar官网:美国男装品牌
2020/02/16 全球购物
如何打造一封优秀的留学推荐信
2014/01/25 职场文书
审计专业自荐信范文
2014/04/21 职场文书
2014年九一八事变演讲稿
2014/09/14 职场文书
2014年街道办事处工作总结
2014/12/11 职场文书
如何写一份成功的商业计划书
2019/06/25 职场文书
Python OpenCV 图像平移的实现示例
2021/06/04 Python
css3新特性的应用示例分析
2022/03/16 HTML / CSS
Golang 对es的操作实例
2022/04/20 Golang
美国运营商 T-Mobile 以 117.83Mb/s 的速度排第一位
2022/04/21 数码科技