• 文件传输


    简单版

    服务端

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    # Author:Mr.yang
    import socket
    import struct
    import os
    import json
    import subprocess
    share_dir=r'E:Moudule_14.网络编程5.文件传输servershare'
    
    '''
    相对于简单版的优化
    1.报头信息少
    2.struct的i格式有限制
    '''
    def run():
        phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        phone.bind(('127.0.0.1',8080))
        phone.listen(5)
    
        print('setting...')
        while True: # 链接循环
            conn,A = phone.accept()
            while True: # 通信循环
                try:
                    #1.接收数据
                    res = conn.recv(8096) #b'get a.txt'
                    print('客户端数据:',res)
    
                    #2.解析命令,提取相应命令参数
                    cmds = res.decode('utf-8').split() #['get','a.txt']
                    filename = cmds[1]
    
                    #3.以读的方式打开文件,读取文件内容发送给客户端
                    #第一步: 制定固定长度的报头
                    header_dic={
                        'filename': filename, #'filename':'a.txt'
                        'md5':'xxdxxx',
                        'file_size':os.path.getsize(r'%s/%s'%(share_dir,filename)) #os.path.getsize('E:Moudule_14.网络编程5.文件传输serversharea.txt')
                    }
    
                    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 ConnectionResetError:
                    break
            conn.close
        phone.close()

    客户端

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    # Author:Mr.yang
    '''
    recv不能设置数值特别大的原因:
    1.在接收文件的时候可能超过指定数值
    2.自己的操作系统的缓存不能无限大,最大也不能超过操作系统的缓存
    '''
    import socket
    import struct
    import json
    download_dir = r'E:Moudule_14.网络编程5.文件传输clientdownload'
    
    phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.connect(('127.0.0.1',8080))
    
    while True:
        #1.发命令
        cmd = input('>>:').strip() #get a.txt
        if not cmd:continue
        phone.send(cmd.encode('utf-8'))
    
        #2.以写的方式打开一个新文件,接收服务端发来的文件的内容,写入到客户的新文件中
        #第一步: 先收报头的长度
        obj = phone.recv(4)
        header_size = struct.unpack('i',obj)[0]
    
        #第二步: 再收报头
        header_bytes = phone.recv(header_size)
    
        #第三步: 从报头中解析出对真实数据的描述信息
        header_json = header_bytes.decode('utf-8')
        header_dic = json.loads(header_json)
        '''
        header_dic={
                    'filename': filename, #'filename':'a.txt'
                    'md5':'xxdxxx',
                    'file_size':os.path.getsize(filename)
                }
        '''
        print(header_dic)
        total_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 < total_size:
                line = phone.recv(1024)
                f.write(line)
                recv_size += len(line)
                print('总大小:%s 已下载大小:%s'%(total_size,recv_size ))
    
    phone.close()

    优化版

    服务端

    import socket
    import struct
    import os
    import json
    import subprocess
    
    share_dir=r'E:Moudule_14.网络编程5.文件传输优化版servershare'
    
    '''
    相对于简单版的优化
    1.报头信息少
    2.struct的i格式有限制
    '''
    def get(conn,cmds):
        filename = cmds[1]
    
        # 3.以读的方式打开文件,读取文件内容发送给客户端
        # 第一步: 制定固定长度的报头
        header_dic = {
            'filename': filename,  # 'filename':'a.txt'
            'md5': 'xxdxxx',
            'file_size': os.path.getsize(r'%s/%s' % (share_dir, filename))
        # os.path.getsize('E:Moudule_14.网络编程5.文件传输serversharea.txt')
        }
    
        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 run():
        phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        phone.bind(('127.0.0.1',8080))
        phone.listen(5)
    
        print('setting...')
        while True: # 链接循环
            conn,A = phone.accept()
            while True: # 通信循环
                try:
                    #1.接收数据
                    res = conn.recv(8096) #b'get a.txt'
                    print('客户端数据:',res)
    
                    #2.解析命令,提取相应命令参数
                    cmds = res.decode('utf-8').split() #['get','a.txt']
                    if cmds[0] == 'get':
                        get(conn,cmds)
                except ConnectionResetError:
                    break
            conn.close
        phone.close()
    
    if __name__ == '__main__':
        run()

    客户端

    import socket
    import struct
    import json
    
    download_dir = r'E:Moudule_14.网络编程5.文件传输优化版clientdownload'
    
    def get(phone,cmds):
        # 2.以写的方式打开一个新文件,接收服务端发来的文件的内容,写入到客户的新文件中
        # 第一步: 先收报头的长度
        obj = phone.recv(4)
        header_size = struct.unpack('i', obj)[0]
    
        # 第二步: 再收报头
        header_bytes = phone.recv(header_size)
    
        # 第三步: 从报头中解析出对真实数据的描述信息
        header_json = header_bytes.decode('utf-8')
        header_dic = json.loads(header_json)
        '''
        header_dic={
                    'filename': filename, #'filename':'a.txt'
                    'md5':'xxdxxx',
                    'file_size':os.path.getsize(filename)
                }
        '''
        print(header_dic)
        total_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 < total_size:
                line = phone.recv(1024)
                f.write(line)
                recv_size += len(line)
                print('总大小:%s 已下载大小:%s' % (total_size, recv_size))
    
    
    def run():
        phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        phone.connect(('127.0.0.1',8080))
    
        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)
    
        phone.close()
    
    if __name__ == '__main__':
        run()
  • 相关阅读:
    GeoServer源码之Dispatcher
    Geoserver开发之OWS是什么?
    GeoServer数据工作空间:怎么设置?
    Java注解:不使用注解的话,也能实现初始化bean吗?
    JSP编译错误无法显示:PWC6033: Unable to compile class for JSP
    Spring Bean初始化失败
    【每日一具17】CAD迷你画图/最新2020R9
    用python爬虫简单网站却有 “多重思路”--猫眼电影
    【每日一具17】CAD迷你画图/最新2020R9
    Python教你如何对 Excel(xlxs文件) 表的读写和处理
  • 原文地址:https://www.cnblogs.com/Mryang123/p/8719708.html
Copyright © 2020-2023  润新知