select版ftp

5. **本次作业实现的需求:**

    1. 使用SELECT或SELECTORS模块实现并发简单版FTP
    2. 允许多用户并发上传下载文件


6. **测试:**  

----------
仅支持上传下载文件

----------

7. **备注:**  

1.程序运行在bin/startclient.py和startserver.py,请先运行server端,在运行client端

2.模拟的本地目录为db/client/目录,下面有两个测试文件a,b

3.模拟的服务器用户家目录为db/server目录

4.当client段或者server端强制退出时,另一端会报错。。

server端

#!/usr/bin/env python
# coding=utf-8
#Author:yang


import select
import socket
import queue,json,os
from conf import settings

def run():
    server = socket.socket()
    server.bind(('localhost',9999))
    server.listen(1000)
    server.setblocking(0)
    msg_dic = {}
    inputs = [server,]
    outputs = []
    while True:
        readable ,writeable,exceptional= select.select(inputs, outputs, inputs )
        for r in readable:
            if r is server:
                conn,addr = r.accept()
                conn.setblocking(0)
                inputs.append(conn)
                msg_dic[conn] = queue.Queue()
            else:
                data = r.recv(1024)
                if data:
                    msg_dic[r].put(data)
                    if r not in outputs:
                        outputs.append(r)
                else:
                    if r in outputs:
                        outputs.remove(r)
                    inputs.remove(r)
                    del msg_dic[r]



        for w in writeable:
            try:
                cmd = msg_dic[w].get_nowait()
            except queue.Empty:
                outputs.remove(w)
            else:
                data = json.loads(cmd.decode())
                if data['action'] == 'put':
                    filesize = data['size']
                    filename = data['filename']
                    file = os.path.join(settings.SERVER_HOME,filename)
                    f = open(file, "wb")
                    received_size = 0
                    while received_size < filesize:
                        data = w.recv(4096)
                        f.write(data)
                        received_size += len(data)
                    else:
                        print('文件下载完毕!')
                        f.close()

                elif data['action'] == 'get':
                    filename = data['filename']
                    file = os.path.join(settings.SERVER_HOME,filename)
                    print(file)
                    if os.path.exists(file):
                        filesize = os.stat(file).st_size
                        w.send(str(filesize).encode('utf-8'))
                        f = open(file, "rb")
                        for line in f:
                            w.send(line)
                        else:
                            print("接收成功")
                            f.close()
                    else:
                        w.sendall('no'.encode('utf-8'))
        for e in exceptional:
            inputs.remove(e)
            if e in outputs:
                outputs.remove(e)
            e.close()
            del msg_dic[e]
server端

client端

#!/usr/bin/env python
# coding=utf-8
#Author:yang

import socket
import json
import os
from conf import settings

def run():
    ftp_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    ftp_client.connect(('localhost',8008))
    while True:
        cmd = input("(仅支持上传下载文件)>>").strip()
        if len(cmd) == 0: continue
        cmd_str = cmd.split()
        if cmd_str[0] == 'put':
            cmd_split = cmd_str[1].split()
            print(cmd_split)
            filename = os.path.join(settings.CLIENT_HOME,cmd_split[0])
            print(filename)
            if os.path.isfile(filename):
                filesize = os.stat(filename).st_size
                msg_dic = {
                    "action": "put",
                    "filename": cmd_split[0],
                    "size": filesize,
                }
                ftp_client.send(json.dumps(msg_dic).encode("utf-8"))
                f = open(filename, "rb")
                for line in f:
                    ftp_client.send(line)
                f.close()

            else:
                print(filename, "文件不存在")

        elif cmd_str[0] == 'get':
            cmd_split = cmd_str[1].split()
            print(cmd_split)
            msg_dic = {
                "action": "get",
                "filename": cmd_split[0],
            }
            ftp_client.send(json.dumps(msg_dic).encode("utf-8"))
            filesize = ftp_client.recv(4096)
            print(filesize)
            if filesize.isdigit() == False:
                print('文件不存在')
            else:
                filesize = int(filesize)
                filename = os.path.join(settings.CLIENT_HOME, cmd_split[0])
                f = open(filename, "wb")
                received_size = 0
                while received_size < filesize:
                    data = ftp_client.recv(4096)
                    f.write(data)
                    received_size += len(data)
                else:
                    print("下载完成!")
                    f.close()
        else:
            print('''
            #         put 文件名         #上传文件
            #         get 文件名         #下载文件
            ''')
client端

 

posted @ 2017-07-26 16:22  咫灵  阅读(480)  评论(0)    收藏  举报