zoukankan      html  css  js  c++  java
  • 文件传送

    简单版

    服务端

    import socket
    import subprocess
    import struct
    import json
    import os
    
    share_dir = r'F:projectookchapter6文件传输简单版本servershare'
    
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # (如果机器中存在,重新用端口)应对端口占用报错情况
    
    phone.bind(("127.0.0.1", 9909))   # 127.0.0.1本地地址,端口范围0-65535:其中0-1024给操作系统使用
    
    phone.listen(5)   # 5代表最大挂起连接数
    
    print("starting...")
    while True:  # 循环链接
        conn, client = phone.accept()  # conn套接字对象
    
        while True:    # 通讯循环
            try:
                # 1、接收命令  (命令:执行系统命令)
                res = conn.recv(8096)  # b'get a.txt
    
                # 2、解析命令,提取相应的命令参数
                cmds = res.decode("utf-8").split()
                filename = cmds[1]
    
                # 3、以读的方式打开文件,读取文件内容,发送给客户端
    
                # 第一步:制作固定长度的报头(import struct)
                header_dic = {
                    "filename": filename,
                    "md5": "xxdxxx",
                    "file_size": os.path.getsize(r"%s/%s" % (share_dir, filename))
                }
                header_json = json.dumps(header_dic)
    
                header_bytes = header_json.encode("utf-8")
    
                # 第二步:先发送报头的长度
                conn.send(struct.pack("i", len(header_bytes)))
    
                # 第三步:再发报头
                conn.send(header_bytes)
    
                # 第四步:再发送真实的数据
                with open("%s/%s" % (share_dir, filename), "rb")as f:
                    # conn.send(f.read())   # 如果文件太大,会占满内存
                    for line in f:
                        conn.send(line)
    
            except ConnectionRefusedError:
                break
    
        conn.close()
    
    phone.close()
    

     客户端

    import socket
    import struct
    import json
    
    download_dir = r"F:projectookchapter6文件传输简单版本clientdownload"
    
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    phone.connect(("127.0.0.1", 9909))  # phone相当于服务端的conn
    
    while True:
        # 1、发命令
        cmd = input(">> ").strip()  # get a.txt
        if not cmd:
            continue
        phone.send(cmd.encode("utf-8"))
    
        # 2、以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户端的新文件中
        # 第一步:先收报头的长度
        header = phone.recv(4)
        header_size = struct.unpack("i", header)[0]
    
        # 第二步:再接收报头信息
        header_bytes = phone.recv(header_size)
    
        # 第三步:从报头中解析出对真实数据的描述信息
        header_json = header_bytes.decode("utf-8")
        header_dic = json.loads(header_json)
        print(header_dic)
        file_size = header_dic["file_size"]
        filename = header_dic["filename"]
    
        # 第四步:接受真实的数据
        with open("%s/%s" % (download_dir, filename), "wb")as f:
            recv_size = 0
            while recv_size < file_size:
                line = phone.recv(1024)
                f.write(line)
                recv_size += len(line)
                print("总大小:%s  已下载大小:%s" % (file_size, recv_size))
    
    phone.close()
    

      


    函数版

    服务端

    import socket
    import subprocess
    import struct
    import json
    import os
    
    share_dir = r'F:projectookchapter6文件传输函数版本servershare'
    
    
    def get(conn, cmds):
        filename = cmds[1]
        # 3、以读的方式打开文件,读取文件内容,发送给客户端
        # 第一步:制作固定长度的报头(import struct)
        header_dic = {
            "filename": filename,
            "md5": "xxdxxx",
            "file_size": os.path.getsize(r"%s/%s" % (share_dir, filename))
        }
        header_json = json.dumps(header_dic)
        header_bytes = header_json.encode("utf-8")
    
        # 第二步:先发送报头的长度
        conn.send(struct.pack("i", len(header_bytes)))
    
        # 第三步:再发报头
        conn.send(header_bytes)
    
        # 第四步:再发送真实的数据
        with open("%s/%s" % (share_dir, filename), "rb")as f:
            # conn.send(f.read())   # 如果文件太大,会占满内存
            for line in f:
                conn.send(line)
    
    
    def put(conn, cmds):
        pass
    
    
    def run():
        phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # (如果机器中存在,重新用端口)应对端口占用报错情况
        phone.bind(("127.0.0.1", 9909))   # 127.0.0.1本地地址,端口范围0-65535:其中0-1024给操作系统使用
        phone.listen(5)   # 5代表最大挂起连接数
    
        print("starting...")
        while True:  # 循环链接
            conn, client = phone.accept()  # conn套接字对象
    
            while True:    # 通讯循环
                try:
                    # 1、接收命令  (命令:执行系统命令)
                    res = conn.recv(8096)  # b'get a.txt
    
                    # 2、解析命令,提取相应的命令参数
                    cmds = res.decode("utf-8").split()
                    if cmds[0] == "get":
                        get(conn, cmds)
                    elif cmds[0] == "put":
                        put(conn, cmds)
                except ConnectionRefusedError:
                    break
    
            conn.close()
    
        phone.close()
    
    
    if __name__ == "__main__":   #如果是执行当前文件的时候,这个条件成立,就执行。如果当前文件被其他文件当成模块导入的时候,这个条件是不成立的,里面的代码是不执行的
        run()
    

     客户端

    import socket
    import struct
    import json
    
    download_dir = r"F:projectookchapter6文件传输函数版本clientdownload"
    
    
    def get(phone, cmds):
        # 2、以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户端的新文件中
        # 第一步:先收报头的长度
        header = phone.recv(4)
        header_size = struct.unpack("i", header)[0]
    
        # 第二步:再接收报头信息
        header_bytes = phone.recv(header_size)
    
        # 第三步:从报头中解析出对真实数据的描述信息
        header_json = header_bytes.decode("utf-8")
        header_dic = json.loads(header_json)
        print(header_dic)
        file_size = header_dic["file_size"]
        filename = header_dic["filename"]
    
        # 第四步:接受真实的数据
        with open("%s/%s" % (download_dir, filename), "wb")as f:
            recv_size = 0
            while recv_size < file_size:
                line = phone.recv(1024)
                f.write(line)
                recv_size += len(line)
                print("总大小:%s  已下载大小:%s" % (file_size, recv_size))
    
    
    def put(phone, cmds):
        pass
    
    
    def run():
        phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
        phone.connect(("127.0.0.1", 9909))  # phone相当于服务端的conn
    
        while True:
            # 1、发命令
            inp = input(">> ").strip()  # get a.txt
            if not inp:
                continue
            phone.send(inp.encode("utf-8"))
            cmds = inp.split()  # ["get","a.txt"]
            if cmds[0] == "get":
                get(phone, cmds)
            elif cmds[0] == "put":
                put(phone, cmds)
        phone.close()
    
    
    if __name__ == "__main__":   # 如果是执行当前文件的时候,这个条件成立,就执行。如果当前文件被其他文件当成模块导入的时候,这个条件是不成立的,里面的代码是不执行的
        run()
    

      


    类版本

    服务端

    import socket
    import subprocess
    import struct
    import json
    import os
    
    # 面相对象的好处可以把数据和操作数据的方法整合到一起
    
    
    class MYServer:
        address_family = socket.AF_INET
        socket_type = socket.SOCK_STREAM
        max_packet_size = 8192
        coding = "utf-8"
        request_queue_size = 5
        allow_reuse_address = False    # 允许地址再用
        server_dir = r"F:projectookchapter6文件传输函数版本servershare"
    
        def __init__(self, server_address, bind_and_activate=True):
            self.server_address = server_address
            self.socket = socket.socket(self.address_family, self.socket_type)
            if bind_and_activate:     #######
                try:
                    self.server_bind()
                    self.server_activate()
                except EOFError:
                    self.server_close()
                    raise      
    
        def server_bind(self):
            if self.allow_reuse_address:
                self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.socket.bind(self.server_address)
            # self.server_address = self.socket.getsockname()  # 本机的IP和端口号
    
        def server_activate(self):
            self.socket.listen(self.request_queue_size)
    
        def server_close(self):
            self.socket.close()
    
        def get_request(self):
            return self.socket.accept()
    
        def close_request(self, request):
            request.close()
    
        def run(self):
            while True:  # 循环链接
                self.conn, self.client_addr = self.get_request()  # conn套接字对象
                print("from client", self.client_addr)
                while True:    # 通讯循环
                    try:
                        head_struct = self.conn.recv(4)
                        if not head_struct:
                            break
                        head_len = struct.unpack('i', head_struct)[0]     # 返回的客户端传送数据的长度
                        head_json = self.conn.recv(head_len).decode(self.coding)       # path
                        head_dic = json.loads(head_json)
                        print(head_dic)
                        # head_dic={'cmd':'put','filename':'a.txt','filesize':123123}
                        cmd = head_dic['cmd']
                        if hasattr(self, cmd):
                            func = getattr(self, cmd)
                            func(head_dic)
                    except ConnectionRefusedError:
                        break
    
        def put(self, args):
            file_path = os.path.normpath(os.path.join(self.server_dir, args['filename']))   # 规范化路径。
            filesize = args['filesize']
            recv_size = 0
            print('----->', file_path)
            with open(file_path, 'wb') as f:
                while recv_size < filesize:
                    recv_data = self.conn.recv(self.max_packet_size)
                    f.write(recv_data)
                    recv_size += len(recv_data)
                    print('recvsize:%s filesize:%s' % (recv_size, filesize))
    
        def get(self, args):      # 下载
            cmd = args[0]
            filename = args[1]
            if not os.path.isfile(filename):
                print('file:%s is not exists' % filename)
                return
            else:
                filesize = os.path.getsize(filename)
    
            head_dic = {'cmd': cmd, 'filename': os.path.basename(filename), 'filesize': filesize}
            print(head_dic)
            head_json = json.dumps(head_dic)
            head_json_bytes = bytes(head_json, encoding=self.coding)
            head_struct = struct.pack('i', len(head_json_bytes))
            self.socket.send(head_struct)
            self.socket.send(head_json_bytes)
            send_size = 0
            with open(filename, 'rb') as f:
                for line in f:
                    self.socket.send(line)
                    send_size += len(line)
                    print(send_size)
    
    
    server = MYServer(('127.0.0.1', 8080))
    server.run()
    

    客户端

    import socket
    import struct
    import json
    import os
    
    
    class MYClient:
        address_family = socket.AF_INET
        socket_type = socket.SOCK_STREAM
        allow_reuse_address = False
        max_packet_size = 8192
        coding = 'utf-8'
        request_queue_size = 5
    
        def __init__(self, server_address, connect=True):
            self.server_address = server_address
            self.socket = socket.socket(self.address_family, self.socket_type)
            if connect:
                try:
                    self.client_connect()
                except EOFError:
                    self.client_close()
                    raise
    
        def client_connect(self):
            self.socket.connect(self.server_address)
    
        def client_close(self):
            self.socket.close()
    
        def run(self):
            while True:
                inp = input(">>: ").strip()
                if not inp:
                    continue
                l = inp.split()
                cmd = l[0]
                if hasattr(self, cmd):
                    func = getattr(self, cmd)
                    func(l)
    
        def put(self, args):     # 上传
            cmd = args[0]
            filename = args[1]
            if not os.path.isfile(filename):
                print('file:%s is not exists' % filename)
                return
            else:
                filesize = os.path.getsize(filename)
    
            head_dic = {'cmd': cmd, 'filename': os.path.basename(filename), 'filesize': filesize}
            print(head_dic)
            head_json = json.dumps(head_dic)
            head_json_bytes = bytes(head_json, encoding=self.coding)
            head_struct = struct.pack('i', len(head_json_bytes))
            self.socket.send(head_struct)
            self.socket.send(head_json_bytes)
            send_size = 0
            with open(filename, 'rb') as f:
                for line in f:
                    self.socket.send(line)
                    send_size += len(line)
                    print(send_size)
                else:
                    print('upload successful')
    
    def get(self, args):   # 下载
        file_path = os.path.normpath(os.path.join(self.server_dir, args['filename']))   # 规范化路径。
        filesize = args['filesize']
        recv_size = 0
        print('----->', file_path)
        with open(file_path, 'wb') as f:
            while recv_size < filesize:
                recv_data = self.conn.recv(self.max_packet_size)
                f.write(recv_data)
                recv_size += len(recv_data)
                print('recvsize:%s filesize:%s' % (recv_size, filesize))
            else:
                print('download successful')
    
    
    client = MYClient(('127.0.0.1', 8080))
    client.run()
    

      

  • 相关阅读:
    面试:div水平垂直居中方案--img自适应
    面试:call、apply、bind原理以及自己手写简易模式
    面试之:判断js类型的方式总结
    git的项目完整操作
    vue3.x版本新建项目相关知识和注意事项
    面试常问平时项目中【Date】的常用操作方法总结
    面试常问平时项目中【Math】的常用操作方法总结
    面试常问平时项目中数组【Array】的常用操作方法总结
    面试常问平时用的对象【Object】的创建方式和常用的对象方法总结
    优化无限列表性能vue-virtual-scroll-list【测试90w条数据】
  • 原文地址:https://www.cnblogs.com/fantsaymwq/p/10051282.html
Copyright © 2011-2022 走看看