标题:萌新学习笔记,FTP文件服务端和客户端
取消只看楼主
zxq0103
Rank: 1
等 级:新手上路
帖 子:36
专家分:0
注 册:2023-3-10
结帖率:0
 问题点数:0 回复次数:0 
萌新学习笔记,FTP文件服务端和客户端
程序代码:
"""
FTP文件服务端
功能:
    1.客户端可以查看服务端有什么文件
    2.客户端可以下载文件
    3.客户端可以上传文件
    4.在客户端打印提示,引导操作
"""
"""
协议:
    1.上传文件  U  up
    2.查看文件  L  list
    3.下载文件  D  down
    4.退出连接  Q  quit
"""

from socket import *
import os,sys,time
from threading import Thread

ADDR = ('0.0.0.0',8888)
FTPDIR = 'D:\\python\\myPython\\my_project\\my_ftp\\ftpfile\\'

class FtpSvr(Thread):
    def __init__(self,connfd,usr):
        self.connfd = connfd
        self.usr = usr
        super().__init__()

    def run(self): # 处理请求
        try:
            while True:
                data = self.connfd.recv(4096).decode()
                # print(data)
                if not data or data == 'Q':
                    print(self.usr,'已经退出FTP')
                    return
                elif data == 'L':
                    self.show_file()
                elif data == 'U':
                    self.up_file()
                elif 'D `' in data:
                    file_name = data.split(' `')
                    self.down_file(file_name[1])
        except:
            return    

    def up_file(self): # 上传文件
        print(self.usr,'请求上传文件')
        self.connfd.send(b'OK')
        file_name = self.connfd.recv(1024)
        if file_name == b'wrong':
            print('传送文件失败')
            return
        print('文件名:',file_name.decode())
        print('开始接收文件')
        with open(FTPDIR + file_name.decode(),'wb') as fw:
            while True:
                data_recv = self.connfd.recv(4096)
                if data_recv == b'finish':
                    print('文件接收完成')
                    return
                else:
                    fw.write(data_recv)
                     
    def down_file(self,file_name): # 下载文件
        print(self.usr,F"请求下载文件:'{file_name}'")
        while True:
            for r, d, files in os.walk(FTPDIR):
                if r[-1] == '\\':
                    file_dir = r+file_name
                else:
                    file_dir = r+'\\'+file_name
                if os.path.isfile(file_dir):
                    # 文件找到,准备传送
                    with open(file_dir,'rb') as f:
                        while True:
                            data = f.read(4096)
                            if data:
                                self.connfd.send(data)
                            else:
                                print('文件传送完毕')
                                self.connfd.send('传送完毕'.encode())
                                return
            else:
                msg = "文件'%s'不存在"%file_name
                print(msg)
                self.connfd.send(msg.encode())
                return
            
    def show_file(self): # 查看文件
        print(self.usr,'请求查看文件列表')
        files = os.listdir(FTPDIR)
        if not files:
            self.connfd.send('文件列表为空'.encode())
            return
        else:
            self.connfd.send(b'OK')
            time.sleep(0.1)

        file_list = ''
        for r, d, files in os.walk(FTPDIR):
            # print(files)
            for file in files:
                if file[0] != '.': #  and os.path.isfile(FTPDIR+file)
                    file_list += file +'\n'
        # print(file_list)
        self.connfd.send(file_list.encode())

def main(): # 主入口,搭建网络模型
    s = socket()
    s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
    s.bind(ADDR)
    print('Server Listen the Port 8888')
    s.listen()
    while True:
        try:
            c,addr = s.accept()
            print('Connect from',addr)
        except KeyboardInterrupt:
            sys.exit('退出服务器')
        except Exception as e:
            print(e)
            continue
        
        svr = FtpSvr(c,addr)
        svr.setDaemon(True) 
        svr.start() 


if __name__ == "__main__":
    main()


程序代码:
"""
FTP文件客户端
功能:
    1.客户端可以查看服务端有什么文件
    2.客户端可以下载文件
    3.客户端可以上传文件
    4.在客户端打印提示,引导操作
"""
"""
协议:
    1.上传文件  U  up
    2.查看文件  L  list
    3.下载文件  D  down
    4.退出连接  Q  quit
"""
from socket import *
import os,sys,time

ADDR = ('127.0.0.1',8888)
FTPDIR = 'D:\\python\\myPython\\my_project\\my_ftp\\recv_file\\'

class FtpClnt:
    def __init__(self,sockfd):
        self.sockfd = sockfd
    
    def up_file(self): # 上传文件
        # print('请求上传文件')
        self.sockfd.send(b'U')
        data = self.sockfd.recv(108)
        if data == b'OK':
            print('====准备上传文件====')
            file_name = input('请输入文件名>>').strip()
            if os.path.isfile(FTPDIR+file_name):
                self.sockfd.send(file_name.encode())
                time.sleep(0.1)
                print('=======开始上传文件=======')
                with open(FTPDIR+file_name,'rb') as fr:
                    while True:
                        data_send = fr.read(4096)
                        if data_send:
                            self.sockfd.send(data_send)
                        else:
                            self.sockfd.send(b'finish')
                            print('文件上传成功')
                            return
            else:
                print('对不起文件不存在')
                self.sockfd.send(b'wrong')
                return
        else:
            print('请求失败,返回命令行')
            return
    
    def down_file(self): # 下载文件
        print('请求下载文件')
        file_name = input('请输入文件名>>').strip() # 去掉因手抖多出的空格
        send_name = 'D `' + file_name
        self.sockfd.send(send_name.encode())
        
        with open(FTPDIR + file_name,'wb') as f:
            while True:
                data_recv = self.sockfd.recv(4096)
                if '不存在'.encode() in data_recv:
                    print(data_recv.decode())
                    f.close()
                    os.remove(FTPDIR + file_name)
                    return
                elif data_recv == '传送完毕'.encode():
                    break
                else:
                    f.write(data_recv)
        print('===========文件下载成功===========')
        print("文件名:%s,存放路径是:recv_file"%file_name)
        return
    
    def show_file(self): # 查看文件
        print('请求查看文件')
        self.sockfd.send(b'L')
        data = self.sockfd.recv(4096)
        if  data == b'OK':
            print('=====文件列表====')
            data = self.sockfd.recv(4096)
            print(data.decode())
        else:
            print(data.decode())
            return
    
    def quit_ftp(self): # 退出FTP
        self.sockfd.send(b'Q')
        self.sockfd.close()

    def show_menu(self): # 构建命令界面
        while True:
            """
                协议:
                    1.上传文件  FU  up
                    2.查看文件  FL  list
                    3.下载文件  FD  down
                    4.退出连接  FQ  quit
            """
            print('\n=====请选择你需要的命令项=====')
            print('=====【命令需要大写字母】=====')
            print("     【查看文件】 =  L")
            print("     【上传文件】 =  U")
            print("     【下载文件】 =  D")
            print("     【退出软件】 =  Q\n")
            
            cmd_input = input('请输入你的选择>>')
            if cmd_input in 'LQUD':
                if cmd_input == 'L': # 查看文件
                    self.show_file()
                elif cmd_input == 'U': # 上传文件
                    self.up_file()
                elif cmd_input == 'D': # 下载文件
                    self.down_file()
                elif cmd_input == 'Q': # 退出FTP服务
                    self.quit_ftp()
                    sys.exit()
            else:
                print('对不起,你输入的不正确')
                print('请重新输入【大写字母】')
                continue

def main(): # 主入口,搭建网络模型
    sockfd = socket()
    try:
        sockfd.connect(ADDR)
    except Exception as e:
        print(e)
        return
    my_ftp = FtpClnt(sockfd)
    print('恭喜你,已经连接到FTP服务器')
    my_ftp.show_menu()
      
        
if __name__ == "__main__":
    main()



[此贴子已经被作者于2023-4-26 07:23编辑过]

搜索更多相关主题的帖子: if send 文件 print data 
2023-04-26 07:18



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-512044-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.058543 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved