第十节

select模块

select模块

select的ftp server端,不过有问题,select只是实现数据的一次请求发送,但是这个模块里用了多次,所以会报错

import json,queue,select,socket,sys
sys.path.append("..")
from core import method

server = socket.socket()
server.bind(("localhost",9000))
server.listen(1000)

server.setblocking(False)   #不阻塞

msg_dic = {}

inputs = [server,]
#inputs = [server,conn,conn2] #[conn2,]
outputs = []
while True:
    readable,writable,exceptional = select.select(inputs,outputs,inputs)
    print(readable,writable,exceptional)
    for r in readable:
        if r is server:
            conn,addr = server.accept()
            print("来了一个新连接",addr)
            inputs.append(conn)
            msg_dic[conn] = queue.Queue()
        else:
            data = r.recv(1024).strip()
            print("收到数据",data)
            cmd_dic = json.loads(data.decode())
            # msg_dic[r].put(cmd_dic)
            # action = cmd_dic["action"]
            # msg_dic[r].put(action)
            func_name = cmd_dic["action"]
            msg_dic[r].put(func_name)
            file_information = method.A(r,cmd_dic)
            msg_dic[r].put(file_information)

            outputs.append(r)

    for w in writable:
        print(w,777777777777)
        func_name2 = msg_dic[w].get()
        data_to_client = msg_dic[w].get()
        func = getattr(method,func_name2)
        print(func,type(func))
        func(w,data_to_client)

        outputs.remove(w)

    for e in exceptional:
        if e in outputs:
            outputs.remove(e)

        inputs.remove(e)

        del msg_dic[e]
./bin/main.py

ftp server端的方法模块

import json
import os


def put(r, filename,filesize):
    """接收客户端文件"""
    if os.path.isfile(filename):
        f = open(filename + ".new", "wb")
    else:
        f = open(filename, "wb")
    r.send(b"200 ok")
    received_size = 0
    while received_size < filesize:
        data = r.recv(1024)
        f.write(data)
        received_size += len(data)
    else:
        print("file [%s] has uploaded..." % filename)


def get(r, filename):
    '''发送给客户端文件'''
    f = open(filename, "rb")
    for line in f:
        r.send(line)
    else:
        print("file transport success!")


def A(r,*args):
    cmd_dic = args[0]
    action = cmd_dic["action"]
    filename = cmd_dic["filename"]
    # filesize = cmd_dic["size"]
    if action == "get":
        if os.path.isfile(filename):
            r.send("ok".encode())
            print("wait....")
            client_ack = r.recv(1024)
            client_ack = client_ack.decode()
            if client_ack == "ok":
                cmd_dic["filesize"] = os.stat(filename).st_size
                r.send(json.dumps(cmd_dic).encode())
                client_response = r.recv(1024)
                client_response = client_response.decode()
                print(client_response, type(client_response))
                if client_response == "ok":
                    return filename
                else:
                    return "client收到filesize但没有回应......."
            else:
                return "client没有确认file是否存在....."
        else:
            r.send("no".encode())
            return "file is not exist!"
    elif action == "put":
        filesize = cmd_dic["size"]
        # put(r,filename,filesize)
        return filename,filesize
./core/method.py

ftp client端

import socket
import os
import json

class FTPclient(object):
    def __init__(self):
        self.client = socket.socket()

    def help(self):
        msg = '''
        ls
        pwd
        cd ../..
        get filename
        put filename
        '''
        print(msg)

    def connect(self,ip,port):
        self.client.connect((ip,port))

    def interactive(self):
        while True:
            cmd = input(">>:").strip()
            if len(cmd) == 0:continue
            cmd_str = cmd.split()[0]
            if hasattr(self,"cmd_%s" % cmd_str):
                function = getattr(self,"cmd_%s" % cmd_str)
                function(cmd)
            else:
                self.help()

    def cmd_put(self,*args):
        cmd_split = args[0].split()
        if len(cmd_split) > 1:
            filename = cmd_split[1]
            if os.path.isfile(filename):
                filesize = os.stat(filename).st_size
                msg_dic = {
                    "action":"put",
                    "filename":filename,
                    "size":filesize,
                    "overridden":True
                }
                self.client.send(json.dumps(msg_dic).encode())
                #f防止粘包,服务器确认
                server_response = self.client.recv(1024)
                f = open(filename,"rb")
                for line in f:
                    self.client.send(line)
                else:
                    print("file upload success")
                    f.close()
            else:
                print(filename,"is not exist!")

    def cmd_get(self,*args):
        cmd_split = args[0].split()
        if len(cmd_split) > 1:
            filename = cmd_split[1]
            msg_dic = {
                "action":"get",
                "filename":filename,
                "filesize":""
            }
            self.client.send(json.dumps(msg_dic).encode())
            #f防止粘包,服务器确认
            file_exist = self.client.recv(1024)
            file_exist = file_exist.decode()
            if file_exist == "ok":
                self.client.send("ok".encode())
                data = self.client.recv(1024)
                msg_dic = json.loads(data.decode())
                filesize = msg_dic["filesize"]
                print(filesize)
                if os.path.isfile(filename):
                    f = open(filename+".new", "wb")
                else:
                    f = open(filename,"wb")
                self.client.send("ok".encode())  #向server发送ack,可以收包了
                received_size = 0
                while received_size < filesize:
                    data = self.client.recv(1024)
                    f.write(data)
                    received_size += len(data)
                else:
                    print("file download completed!")
                    f.close()
            else:
                print("file is not exist in server!")

ftp = FTPclient()
ftp.connect("localhost",9000)
ftp.interactive()
client.py

 

posted @ 2017-09-10 11:25  酷酷的狐狸  阅读(212)  评论(0编辑  收藏  举报