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实现list反转实例汇总
Nov 11 Python
Windows下安装python2.7及科学计算套装
Mar 05 Python
python实现文本去重且不打乱原本顺序
Jan 26 Python
pytorch cnn 识别手写的字实现自建图片数据
May 20 Python
Python爬虫框架Scrapy常用命令总结
Jul 26 Python
python 读取竖线分隔符的文本方法
Dec 20 Python
python matplotlib画图库学习绘制常用的图
Mar 19 Python
基于python全局设置id 自动化测试元素定位过程解析
Sep 04 Python
python sorted方法和列表使用解析
Nov 18 Python
Python 解码Base64 得到码流格式文本实例
Jan 09 Python
Python集合操作方法详解
Feb 09 Python
新手学习Python2和Python3中print不同的用法
Jun 09 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
浅析Mysql 数据回滚错误的解决方法
2013/08/05 PHP
php中preg_match的isU代表什么意思
2015/10/01 PHP
[原创]php常用字符串输出方法分析(echo,print,printf及sprintf)
2016/07/09 PHP
laravel 获取当前url的别名方法
2019/10/11 PHP
!DOCTYPE声明对JavaScript的影响分析
2010/04/12 Javascript
jQuery点击tr实现checkbox选中的方法
2013/03/19 Javascript
JS操作Cookie写入和读取实例代码
2013/10/20 Javascript
JS不间断向上滚动效果代码
2013/12/25 Javascript
分享2个jQuery插件--jquery.fileupload与artdialog
2014/12/26 Javascript
JavaScript表格常用操作方法汇总
2015/04/15 Javascript
Bootstrap每天必学之栅格系统(布局)
2015/11/25 Javascript
jqPlot jQuery绘图插件的使用
2016/06/18 Javascript
jQuery实现锚点向下平滑滚动特效示例
2017/08/29 jQuery
vue-cli开发时,关于ajax跨域的解决方法(推荐)
2018/02/03 Javascript
浅谈Koa2框架利用CORS完成跨域ajax请求
2018/03/06 Javascript
JS中DOM元素的attribute与property属性示例详解
2018/09/04 Javascript
基于Vue的侧边目录组件的实现
2020/02/05 Javascript
Python的一些用法分享
2012/10/07 Python
Python基于PycURL自动处理cookie的方法
2015/07/25 Python
对json字符串与python字符串的不同之处详解
2018/12/19 Python
Python面向对象思想与应用入门教程【类与对象】
2019/04/12 Python
十个Python练手的实战项目,学会这些Python就基本没问题了(推荐)
2019/04/26 Python
python+OpenCV实现车牌号码识别
2019/11/08 Python
Python: tkinter窗口屏幕居中,设置窗口最大,最小尺寸实例
2020/03/04 Python
Python中常用的os操作汇总
2020/11/05 Python
科沃斯机器人官网商城:Ecovacs
2016/08/29 全球购物
中国电子产品批发商/跨境电商/外贸网:Sunsky-online
2020/04/20 全球购物
会计专业毕业自荐书范文
2014/02/08 职场文书
百货商场楼层班组长竞聘书
2014/03/31 职场文书
2014年个人债务授权委托书范本
2014/09/22 职场文书
刑事辩护授权委托书格式
2014/10/13 职场文书
军人离婚协议书样本
2014/10/21 职场文书
导游词之徐州-云龙山
2019/09/29 职场文书
python opencv通过按键采集图片源码
2021/05/20 Python
MySQL外键约束(FOREIGN KEY)案例讲解
2021/08/23 MySQL
「我的青春恋爱物语果然有问题。-妄言录-」第20卷封面公开
2022/03/21 日漫