Python实现的FTP通信客户端与服务器端功能示例

作者:chengqiuming 时间:2023-10-02 21:36:01 

本文实例讲述了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程序设计有所帮助。

来源:https://blog.csdn.net/chengqiuming/article/details/78601165

标签:Python,FTP通信,客户端,服务器端
0
投稿

猜你喜欢

  • python基础教程之基本内置数据类型介绍

    2023-02-12 07:19:31
  • Django解决frame拒绝问题的方法

    2023-04-13 22:00:06
  • Python多线程:主线程等待所有子线程结束代码

    2021-03-18 05:31:53
  • asp 去掉html中的table正则代码函数

    2011-04-06 10:48:00
  • 用正则替换所有URL

    2009-03-13 13:51:00
  • wxpython自定义下拉列表框过程图解

    2023-11-14 04:01:18
  • python爬虫selenium和phantomJs使用方法解析

    2023-02-06 19:23:38
  • Python格式化文本段落之textwrap库

    2023-11-23 00:40:56
  • Tkinter组件Checkbutton的具体使用

    2023-03-19 14:55:46
  • python @classmethod 的使用场合详解

    2023-08-02 20:50:35
  • 详谈vue中router-link和传统a链接的区别

    2024-04-09 10:46:05
  • python爬虫教程之bs4解析和xpath解析详解

    2023-09-22 19:43:06
  • 巧妙规划使用Oracle数据空间

    2009-03-20 11:51:00
  • ms SQL server数据库备份、压缩与SQL数据库数据处理的方法

    2024-01-18 14:54:04
  • 浅析Python requests 模块

    2023-04-28 17:45:18
  • Go语言程序开发gRPC服务

    2024-04-23 09:38:02
  • python中的内置函数getattr()介绍及示例

    2023-01-15 19:16:46
  • Python统计可散列的对象之容器Counter详解

    2023-09-23 18:30:50
  • python高手之路python处理excel文件(方法汇总)

    2021-02-17 10:33:15
  • 用Python监控NASA TV直播画面的实现步骤

    2022-09-15 21:54:15
  • asp之家 网络编程 m.aspxhome.com