zoukankan      html  css  js  c++  java
  • python 网络编程-04 文件的传输

    1. 文件传输需要要hashlib 来验证文件的完整性
    2. 需要判断文件是否传输完成

    文件完整性判断

    import hashlib
    md5 = hashlib.sha3_256()
    md5.update(msg)
    

    update 为追加完整性判断

    md5.update(b'hello world')
    与
    md5.update(b'hello ')
    md5.update(b'world')
    

    hash 值完全相同

    实现

    proto.py

    import struct
    import hashlib
    
    
    def sender(conn, msg: bytes):
    
        pack_head = struct.pack('i', len(msg))
        conn.send(pack_head)
        conn.send(msg)
    
    
    def receiver(conn) -> str:
        length = struct.unpack('i', conn.recv(4))[0]
        msg = ''
        while True:
            if length < 1024:
                recv_msg = conn.recv(length)
                msg += recv_msg.decode('utf-8')
                break
            else:
                recv_msg = conn.recv(1024)
                length -= 1024
                msg = recv_msg.decode('utf-8')
    
        return msg
    
    
    class HashCheck:
        def __init__(self):
            self.md5 = hashlib.sha3_256()
    
        def hash_md5(self, msg: bytes):
            self.md5.update(msg)
    
    

    server.py

    import socket, traceback
    from 文件传送与文件校验 import proto
    
    
    def recv_file(c, filename):
        md5obj = proto.HashCheck()
        with open(filename, 'w') as f:
            """
            1. 获取文件大小
            2. 循环获取文件行
            3. 追加验证文件完整性,并将文件行内容写入文件
            4. 文件读完后 获取文件的MD5
            5. 将获取的MD5与 计算的MD5 进行比较。
            """
    
            size = proto.receiver(c)
            file_size = int(size)
            while True:
                try:
                    line = proto.receiver(c)
                    md5obj.hash_md5(line.encode('utf-8'))
                    f.write(line)
                    file_size -= len(line)
    
                    #  文件接收完成
                    if file_size == 0:
                        break
    
                except Exception as e:
                    print('连接异常')
                    c.close()
                    print(traceback.print_exc())
                    break
            hash_md5 = proto.receiver(c)
            if hash_md5 == md5obj.md5.hexdigest():
                print('file receive success!')
            else:
                print('file receive failed!')
    
    
    if __name__ == '__main__':
        s = socket.socket()
        s.bind(('127.0.0.1', 8000))
        s.listen()
        while True:
            print('等待连接')
            conn, addr = s.accept()
    
            recv_file(conn, 'server1.txt')
    
    

    client.py

    import socket
    import os
    from 文件传送与文件校验 import proto
    
    
    def send_file(filename):
        s = socket.socket()
        s.connect(('127.0.0.1', 8000))
        # 获取文件大小
        size = os.path.getsize(filename)
        # 发送文件大小
        proto.sender(s, str(size).encode('utf-8'))
    
        with open(filename, 'rb') as f:
            # 创建md5 的验证对象
            md5obj = proto.HashCheck()
            for line in f:
                # 追加MD5 验证
                md5obj.hash_md5(line)
                # 发送文件行
                proto.sender(s, line)
        proto.sender(s, md5obj.md5.hexdigest().encode('utf-8'))
        s.close()
    
    
    if __name__ == '__main__':
        send_file('client.txt')
    
    
  • 相关阅读:
    快速排序理论---不含源码
    归并排序理论---不含源码
    希尔排序(shell)理论---不含源码
    Visual C++中error spawning cl.exe解决办法
    数据库的基础知识点---1
    冒泡排序的基础知识部分(不含源码)
    在虚拟机的Linux系统下安装wineqq
    数据变量的别名
    void*和void类型
    变量的作用域和连接性
  • 原文地址:https://www.cnblogs.com/pythonPath/p/12402760.html
Copyright © 2011-2022 走看看