琪齐

空想终日彷徨行动方可无惧!

导航

开发一个支持多用户在线的FTP程序

Posted on 2016-06-13 17:56  琪齐  阅读(323)  评论(0)    收藏  举报

开发一个支持多用户在线的FTP程序

要求:

1、用户md5加密认证

2、允许同时多用户登录(socketserver)
3、执行命令,
客户端:ipconfig
服务器:subprocess.
==> 能够聊天

4、上传文件(文件名)
文件传输过程中显示进度条
支持文件的断点续传(可选)

自己实现最low的:

服务端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import socketserver
import subprocess
import hashlib
import os

def md5(arg):
    hash = hashlib.md5(bytes('dshdfj',encoding="utf-8"))
    hash.update(bytes(arg,encoding="utf-8"))
    return hash.hexdingest()

def login(user ,pwd):
    with open("log.txt","r",encoding="utf-8") as f:
        for line in f:
            u,p = line.strip().split("$")
            if u == user and p == md5(pwd):
                return True
            else:
                return False

def register(user,pwd):
    with open("log.txt","a",encoding="utf-8") as f:
        temp = user + "$" + md5(pwd) + "\n"
        f.write(temp)


class MyServer(socketserver.BaseRequestHandler):

    def handle(self):
        conn = self.request
        conn.sendall(bytes('***欢迎登录英雄联盟***', encoding='utf-8'))
        print()
        while True:
            ret_bytes = conn.recv(1024)
            ret_str = str(ret_bytes,encoding="utf_8")
            print(ret_str)

            if ret_str == "1":
                conn.sendall(bytes("ack",encoding="utf-8"))
                lg = set(conn.recv(1024),encoding="utf-8")
                user,pwd = lg.split("$")
                if login(user,pwd):
                    conn.sendall(bytes("True",encoding="utf-8"))
                else:
                    conn.sendall(bytes("False",encoding="utf-8"))
            elif ret_str == "q":
                break

            elif ret_str == "2":
                conn.sendall(bytes("asd",encoding="utf-8"))
                ret_str = str(conn.recv(1024),encoding="utf-8")
                user,pwd = ret_str.strip("$")
                print(user,pwd)
                register(user,pwd)
            elif ret_str == "3":
                conn.sendall(bytes("dfg",encoding="utf-8"))
                ret_str = str(conn.recv(1024),encoding="utf-8")
                obj = subprocess.check_output(ret_str)
                conn.sendall(obj)
            elif ret_str == "4":
                conn.sendall(bytes("***欢迎进入英雄联盟***",encoding="utf-8"))
                print()
                while True:
                    ret_str = str(conn.recv(1024),encoding="utf-8")
                    if ret_str == "q":
                        conn.sendall(bytes("欢迎下次登录",encoding="utf-8"))
                        break
                    elif ret_str == "1":
                        print(ret_str,type(ret_str))
                        chaxun = "查询信息:"\
                                 "\n1.查询英雄,\n2.查询皮肤,\n3.查询战斗力"
                        conn.sendall(bytes(chaxun,encoding="utf-8"))
                    elif ret_str == "2":
                        print(ret_str,type(ret_str))
                        friend = "查看好友:"\
                                    "\n1.游戏好友,\n2.扣扣好友,"
                        conn.sendall(bytes(friend,encoding="utf-8"))
                    elif ret_str == "3":
                        print(ret_str,type(ret_str))
                        watching = "是否观战:"\
                                    "\n1.观战,\n2.不观战"
                        conn.sendall(bytes(watching,encoding="utf-8"))
                    else:
                        conn.sendall(bytes("输入有误请您重新输入!", encoding='utf-8'))
            elif ret_str == "5":
                BASE_DIR = os.path.dirname(os.path.abspath(__file__))

                zuoye = os.path.join(BASE_DIR,"zuoye/day")
                sk = socket.socket()
                sk.listen(5)
                while True:
                    print("准备上传")
                    conn,addr = sk.accept()
                    conn.sendall(bytes("欢迎登录",encoding="utf8"))
                    flag = True
                    while flag:
                        ret_bytes = conn.recv(1024)
                        ret_str = str(ret_bytes,encoding="utf8")

                        func,file_name,file_size,target = ret_str.split("|",3)
                        file_size = int(file_size)
                        path = os.path.join(zuoye,file_name)

                        has_received = 0

                        if os.path.exists(path):
                            conn.sendall(bytes("cunzai","utf8"))
                            is_continue = str(conn.recv(1024),"utf8")
                            if is_continue == "cz":
                                has_size = os.stat(path).st_size
                                conn.sendall(bytes(str(has_size),"utf8"))
                                has_received += has_size

                                f = open(path,"ab")
                            else:
                                f = open(path,"wb")
                        else:
                            conn.sendall(bytes("cunzai","utf8"))
                            f = open(path,"wb")

                        while has_received < file_size:
                            try:
                                data = conn.recv(1024)
                                if not data:
                                    raise Exception
                            except Exception:
                                flag = False
                                break

                            f.write(data)
                            has_received += len(data)
                        print("成功")
                        f.close()


if __name__ == "__main__":
    server = socketserver.ThreadingTCPServer(("127.0.0.1", 8889),MyServer)
    server.serve_forever()

客户端

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket
import os
import re


sk = socket.socket()
sk.connect(("127.0.0.1", 8889))

ret_bytes = sk.recv(1024)
ret_str = str(ret_bytes, encoding='utf-8')
print(ret_str)
while True:
    inp = input("请输入:1登录,2注册,3执行命令,4客服语音,5上传(q退出),\n>>>")
    if inp == "1":
        sk.sendall(bytes(inp,encoding="utf-8"))
        sk.recv(1024)
        user = input("请输入用户名:")
        pwd = input("请输入用户密码:")
        up = user + "$" + pwd
        sk.sendall(bytes(up,encoding="utf-8"))
        if str(sk.recv(1024),encoding="utf-8"):
            print("登录成功")
        else:
            print("登录失败")

    elif inp == "2":
        sk.sendall(bytes(inp,encoding="utf-8"))
        sk.recv(1024)
        user = input("请输入用户名:")
        pwd = input("请输入用户密码:")
        up = user + "$" + pwd
        sk.sendall(bytes(up,encoding="utf-8"))
    elif inp == "q":
        sk.sendall(bytes(inp, encoding="utf-8"))
        break

    elif inp == "3":
        sk.sendall(bytes(inp,encoding="utf-8"))
        sk.recv(1024)
        ret = input("请输入命令:")
        sk.sendall(bytes(ret,encoding="utf-8"))
        log = sk.recv(1024)
        print(log)


    elif inp == "4":
        sk.sendall(bytes(inp,encoding="utf-8"))
        sk.recv(1024)
        while True:
            inp = input("请输入内容:1查询信息,2查看好友,3是否观战(q退出),\n>>>")
            sk.sendall(bytes(inp, encoding='utf-8'))

            if inp == 'q':
                ret_str = str(sk.recv(1024), encoding='utf-8')
                print(ret_str)
                break
            else:
                sk.sendall(bytes(inp, encoding='utf-8'))
                ret = str(sk.recv(1024), encoding='utf-8')
                print(ret)

    elif inp == "5":
        sk = socket.socket()
        while True:
            inp = input("请输入上传文件名和路径:")
            func,file = input.split("|",1)
            local,target = re.split("\s*",file,1)
            file_size = os.stat(local)
            file_name = os.path.basename(local)
            post_info = "post|%s|%s|%s"%(file_name,file_size,target)
            sk.sendall(bytes(post_info,encoding="utf-8"))
            ret_exist = str(sk.recv(1024),encoding="utf-8")
            has_sent = 0
            if ret_exist == "cunzai":
                inp = input("文件存在是否续传:Y.是,\n>>>")
                if inp == "Y":
                    sk.sendall(bytes("cz",encoding="utf-8"))
                    ret_continue = str(sk.recv(1024),encoding="utf-8")
                    print(ret_continue)
                    has_sent = int(ret_continue)
                else:
                    sk.sendall(bytes("bx",encoding="utf-8"))
            file_sk = open(local,"rb")
            file_sk.seek(has_sent)

            while has_sent < file_size:
                data = file_sk.read(1024)
                sk.sendall(data)
                has_sent += len(data)

            file_sk.close()
            print("上传成功")


sk.close()

 

断点续传在:http://www.cnblogs.com/kongqi816-boke/p/5570624.html