zoukankan      html  css  js  c++  java
  • 第七周作业——简单FTP

    开发简单的FTP:

    1. 用户登陆

    2. 上传/下载文件

    3. 不同用户家目录不同

    4. 查看当前目录下文件

    5. 充分使用面向对象知识

    1、目录结构
    zuoye-ftp
    ├── chenliang #用户chenliang的FTP根目录
    ├── download #所有用户下载的时候默认文件路径
    ├── lw #用户lw的FTP根目录
    ├── lzd #用户lzd的FTP根目录
    ├── wangjun #用户wangjun的FTP根目录
    ├── wdl #用户wdl的FTP根目录
    ├── xueli #用户xueli的FTP根目录
    ├── create-users.py #创建用户专用py文件
    ├── ros.zip #模拟上下载的测试文件ros.zip
    ├── socket_client.py #客户端文件
    ├── socket_server.py #服务端文件
    ├── user_data.bak #shelve文件
    ├── user_data.dat #shelve文件
    └── user_data.dir #shelve文件

    2、创建用户运行create-users.py,默认帐号密码是一致的。已有用户chenliang,lw,lzd,wangjun,wdl,xueli
    3、创建的用户,在执行服务端的时候,自动会生成一个自己用户的FTP根目录,同时便于测试会复制ROS.zip到自己根目录
    4、先运行socket_server.py,默认socket的服务端端口号为6969
    5、再运行socket_client.py

    create-users.py

    #!/usr/bin/env python
    #-*-coding:utf-8-*-
    #Author:lzd
    #创建用户名和密码,默认用户名和密码一致
    import shelve
    userlist=[]
    user_data=shelve.open("user_data")
    # for i in user_data.items():
    #     print(i)
    print("当前已有的所有用户的用户名如下:")
    for i in user_data.keys():
        userlist.append(user_data[i])
    print(userlist)
    while True:
        username=input("请输入用户名
    ")
        if username in userlist:
            print("用户名重复啦,请重新输入用户名!")
            continue
        else:
            password=input("请输入用户密码
    ")
        break
    user_data[username]=password
    user_data.close()
    print("用户创建成功~!")

    socket_server.py

    #!/usr/bin/env python
    #-*-coding:utf-8-*-
    #Author:lzd
    #服务器端
    import os
    gongzuopath=os.getcwd()
    # print(gongzuopath)
    import time
    #print(time.strftime("%Y%m%d%H%M%S",time.localtime()))
    import socket
    server = socket.socket()
    server.bind(('localhost',6969)) #绑定要监听端口
    server.listen() #监听
    import shutil
    import shelve
    userlist=[]
    user_data=shelve.open("user_data")
    for i in user_data.keys():
        userlist.append(user_data[i])
        if not os.path.exists(gongzuopath+r"/"+i):
            os.mkdir(gongzuopath+r"/"+i)
        if not os.path.exists(gongzuopath+r"/"+i+"/ros.zip"):
            shutil.copyfile(gongzuopath+r"/ros.zip",gongzuopath+r"/"+i+"/ros.zip")
    print("我要开始等电话了")
    while True:
        Flag = True
        conn, addr = server.accept()  # 等电话打进来
        # conn就是客户端连过来而在服务器端为其生成的一个连接实例
        print(conn, addr)
        print("电话来了")
        while Flag:
            data = conn.recv(1024)
            print("recv:",data)
            if not data:
                print("client has lost...")
                break
            clientuser=data.decode("utf-8")
            if clientuser in userlist:
                conn.send("请输入用户密码".encode("utf-8"))
                data = conn.recv(1024)
                print("recv:",data)
                if not data:
                    print("client has lost...")
                    break
                if data.decode("utf-8")==user_data[clientuser]:
                    conn.send("用户名密码验证成功".encode("utf-8"))
                    while Flag:
                        data = conn.recv(1024)
                        print("recv:", data)
                        if data=="choose3".encode("utf-8"):
                            if ",".join(os.listdir(gongzuopath+r"/"+clientuser)).encode("utf-8"):
                                conn.send(",".join(os.listdir(gongzuopath+r"/"+clientuser)).encode("utf-8"))
                            else:
                                conn.send("当前目录下为空".encode("utf-8"))
                        elif data=="choose1".encode("utf-8"):
                            conn.send("服务端准备接收文件".encode())
                            data = conn.recv(1024).decode("utf-8") #收到文件大小,单位byte
                            filesize=data
                            print("recv:文件大小为", data)
                            tmpdata="服务端准备接收大小为"+data+"的文件"
                            conn.send(tmpdata.encode())
                            serverfile=gongzuopath+r"/"+clientuser+"/"+time.strftime("%Y%m%d%H%M%S",time.localtime())
                            f = open(serverfile, "wb")
                            while str(os.stat(serverfile).st_size) != filesize:
                                data=conn.recv(10240000)
                                f.write(data)
                                f.flush()
                            else:
                                conn.send("文件发送完毕".encode("utf-8"))
                        elif data=="choose2".encode("utf-8"):
                            if ",".join(os.listdir(gongzuopath + r"/" + clientuser)).encode("utf-8"):
                                conn.send(",".join(os.listdir(gongzuopath + r"/" + clientuser)).encode("utf-8"))
                            else:
                                conn.send("当前目录下为空".encode("utf-8"))
                                continue
                            data = conn.recv(1024).decode("utf-8")
                            print(data)
                            if not data:
                                continue
                            print("recv:客户端要下载的文件名", data)
                            fpath=gongzuopath+r"/"+clientuser+r"/"+data
                            fpath_size = str(os.stat(fpath).st_size)
                            f = open(fpath, "rb")
                            filedata = f.read()
                            conn.send(fpath_size.encode("utf-8"))
                            conn.sendall(filedata)
                            data = conn.recv(1024)
                            print(data.decode("utf-8"))  # 文件接收完毕
                        elif data=="choose4".encode("utf-8"):
                            Flag=False
                else:
                    conn.send("用户名密码验证失败".encode("utf-8"))
            else:
                conn.send("输入的用户名不存在".encode())
    
    server.close()

    socket_client.py

    #!/usr/bin/env python
    #-*-coding:utf-8-*-
    #Author:lzd
    #客户端
    import socket
    import os
    gongzuopath=os.getcwd()
    # print(os.stat(gongzuopath+"/lzd/"+"ros.zip").st_size)
    client = socket.socket() #声明socket类型,同时生成socket连接对象
    client.connect(('localhost',6969))
    while True:
        username=input("请输入用户名
    ")
        if len(username) == 0: continue
        client.send(username.encode("utf-8"))
        data=client.recv(1024)
        print(data.decode())
        if data.decode()=="请输入用户密码":
            password=input("")
            client.send(password.encode("utf-8"))
            data=client.recv(1024)
            print(data.decode())
            if data.decode()=="用户名密码验证失败":
                continue
            elif data.decode()=="用户名密码验证成功":
                while True:
                    print("%s当前的工作目录为/%s"%(username,username))
                    print("""
                    1、上传文件;
                    2、下载文件;
                    3、查看当前目录下的所有文件;
                    4、退出程序
                    请输入你想操作的数字?           
                    """)
                    choose=input("")
                    if choose=="1":
                        print("当前用户的工作目录下所有文件如下:")
                        print(",".join(os.listdir(gongzuopath + r"/" + username)))
                        fpath2=input("请输入你想上传到服务器的文件名,为便于测试,当前目录下有个1M的文件ros.zip
    ")
                        print("默认会在当前用户的目录下生成一个当前时间的文件。")
                        if not fpath2:
                            continue
                        fpath=gongzuopath+r"/"+username+r"/"+fpath2
                        fpath_size=str(os.stat(fpath).st_size)
                        f=open(fpath,"rb")
                        filedata=f.read()
                        client.send("choose1".encode("utf-8"))
                        data = client.recv(1024)
                        print(data.decode("utf-8")) #服务器准备接收文件
                        client.send(fpath_size.encode("utf-8"))
                        data = client.recv(1024)
                        print(data.decode("utf-8")) #服务端准备接收大小为%s的文件
                        client.sendall(filedata)
                        data = client.recv(1024)
                        print(data.decode("utf-8"))  # 文件发送完毕
                    if choose=="2":
                        client.send("choose2".encode("utf-8"))
                        data = client.recv(1024)
                        print("您当前的工作目录下,所有的文件如下:")
                        print(data.decode("utf-8"))  # 显示当前工作目录下所有文件
                        if data.decode("utf-8")=="当前目录下为空":
                            continue
                        print("您想下载哪个文件到本地?默认下载到当前脚本的工作目录的download目录")
                        fpath2 = input("请输入你想下载的文件名
    ")
                        client.send(fpath2.encode("utf-8"))
                        fpath = gongzuopath + r"/download/" + fpath2
                        data = client.recv(1024).decode("utf-8")
                        file_size=data
                        print("您想下载的文件大小为:",data)
                        f = open(fpath, "wb")
                        while str(os.stat(fpath).st_size) != file_size:
                            data = client.recv(10240000)
                            f.write(data)
                            f.flush()
                        else:
                            client.send("文件接收完毕".encode("utf-8"))
                            print("文件接收完毕")
                    if choose=="3":
                        client.send("choose3".encode("utf-8"))
                        data = client.recv(1024)
                        print("您当前的工作目录下,所有的文件如下:")
                        print(data.decode("utf-8"))
                    if choose=="4":
                        client.send("choose4".encode("utf-8"))
                        client.close()
                        exit()
  • 相关阅读:
    8月份的To-Do List
    Block作为返回值时的使用
    Block作为参数时的使用
    AFNetwork 作用和用法详解
    UIScrollView监听静止的数种情况
    UIAppearance
    自定义Log实现条件编译
    事件的基本概念
    ubuntu16.04下安装MySQL
    在Ubuntu16.04下搭建samba,实现linux与windows之间的资源共享
  • 原文地址:https://www.cnblogs.com/itfat/p/7618112.html
Copyright © 2011-2022 走看看