网络编程
位置:首页>> 网络编程>> Python编程>> Python实现的FTP通信客户端与服务器端功能示例

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

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

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

本文实例讲述了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

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com