使用socket和socketserver 实现文件的上传和下载

本文展示了如何使用Python的socket和socketserver模块实现文件的上传和下载功能。通过创建客户端和服务器端的类,实现了交互式的文件传输操作,包括ls、cd、get和put命令。在Windows平台上运行,适用于Python 3.x。
摘要由CSDN通过智能技术生成

python 网络编程 实现文件的上传下载,在python 3.x ,运行在window平台。。

 

  • """
    客户端
    """
    
    import os
    import socket
    import json
    
    
    class FtpClient(object):
    
        def __init__(self):
            self.client = socket.socket()
    
        def connect(self,ip,port):
            self.client.connect((ip,port))
    
        def help(self):
            msg = """
                 ls
                 cd ../..
                 get filename
                 put filename
            """
            print(msg)
    
        def interactive(self):
            # self.authenticate
            while True:
                cmd = input(">>:").strip()
                if cmd == 0 : continue
                cmd_str = cmd.split()[0]
                if hasattr(self,"cmd_%s" % cmd_str):
                    print(cmd_str)
                    """
                    hasattr()用于判断类中是否包含某种方法,
                    有就返回 Ture,没有就返回 False
                    """
                    func = getattr(self,"cmd_%s" % cmd_str)
                    print(cmd_str)
                    """
                    getattr()用于判断类中是否包含有某种方法,如有相应的方法则返回类的方法的内存地址,
                    加()调用类方法
                    """
                    func(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
                    }
                    self.client.send(json.dumps(msg_dic).encode("utf-8"))
                    print(json.dumps(msg_dic))
                    #防止粘包 等待服务器端确认
                    server_rp = self.client.recv(1024)
                    f = open(filename,"rb")
                    for l in f:
                        self.client.send(l)
                    else:
                        print("上传完成。。。")
                        f.close()
                else:
                    print(filename,"文件不存在")
    
        def cmd_get(self,*args):
            cmd_split = args[0].split()
            if len(cmd_split) > 1:
                filename = cmd_split[1]
                print(filename)
            msg_dic = {
                "action": "get",
                "filename": filename,
            }
            self.client.send(json.dumps(msg_dic).encode("utf-8"))
    
            if os.path.isfile(filename):
                f = open(filename + ".new", "wb")
            else:
                f = open(filename, "wb")
            filesize = self.client.recv(1024).decode("utf-8")
            #print(type(filesize))
            print(filesize)
            self.client.send(b"200 ok")
            rece_size = 0
            while rece_size < int(filesize):
                data = self.client.recv(1024)
                f.write(data)
                rece_size += len(data)
            else:
                print("下载完成")
            pass
    
    
    ftp = FtpClient()
    ftp.connect("localhost",9994)
    ftp.interactive()
  • """
    服务器端
    """
    import socketserver
    import json,os
    
    
    class MyTCPHangler(socketserver.BaseRequestHandler):
    
        def put(self,*args):
            """接受客户端的文件"""
            cmd_dic = args[0]
            filename = cmd_dic["filename"]
            filesize = cmd_dic["size"]
            if os.path.isfile(filename):
                f = open(filename+".new","wb")
            else:
                f = open(filename , "wb")
            self.request.send(b"200 ok")
            rece_size = 0
            while rece_size < filesize:
                data = self.request.recv(1024)
                f.write(data)
                rece_size += len(data)
            else:
                print("上传完成")
        def get(self,*args):
            print(args)
            filename = args[0]["filename"]
            print(filename)
    
            if os.path.isfile(filename):
                filesize = os.stat(filename).st_size
                msg_dic = {
                    "action": "get",
                    "filename": filename,
                    "size": filesize
                }
                self.request.send(str(filesize ).encode("utf-8"))
               # print(json.dumps(msg_dic))
                # 防止粘包 等待服务器端确认
                server_rp = self.request.recv(1024)
                print(server_rp)
                f = open(filename, "rb")
                for l in f:
                    self.request.send(l)
                else:
                    print("发送完成。。。")
                    f.close()
    
        def handle(self):
            while True:
                try:
                    self.data = self.request.recv(1024).strip()
                    print("{} wrote:".format(self.client_address[0]))
                    print(self.data)
                    cmd_dic = json.loads(self.data.decode())
                    action = cmd_dic["action"]
                    if hasattr(self,action):
                        func = getattr(self,action)
                        func(cmd_dic)
                    #self.request.send(self.data.upper())
                except ConnectionResetError as e:
                    print(e)
                    break
    
    if __name__ == "__main__":
        host,port = "localhost",9994
        #s = socketserver.TCPServer((host,port),MyTCPHangler)
        """ 同时只能链接一个  """
        s = socketserver.ThreadingTCPServer((host, port), MyTCPHangler) #实例化一下对象
        """ThreadingTCPServer 每次来一个链接启动一个进程 这就可以个设备同时链接"""
        s.serve_forever()
    

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值