python sockets发送文件函数说明

问题描述

我正在尝试学习 python 套接字编程(网络),我有一个发送文件函数,但我没有完全理解这个函数的每一行(无法理解)。有人可以逐行解释这是做什么的。我也不确定为什么它需要数据的长度来发送文件。另外,如果您能看到此功能的任何改进,谢谢。

def send_file(socket,filename):
    with open(filename,"rb") as x:
        data = x.read()
        length_data = len(data)
        try:
            socket.sendall(length_data.to_bytes(20,'big'))
            socket.sendall(data)
        except Exception as error:
            print("Error",error)

解决方法

这个协议被写成首先发送文件的大小,然后是它的数据。大小为 20 个八位字节(字节),序列化为“大端”,这意味着首先发送最高有效字节。假设你有一个 1M 的文件,

>>> val = 1000000
>>> val.to_bytes(20,'big')
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0fB@'

程序发送这 20 个字节,然后发送文件负载本身。接收器将读取 20 个八位字节,将其转换回文件大小,并确切知道要为文件接收多少个八位字节。 TCP 是一种流媒体协议。它不知道消息边界。协议需要某种方式来告诉对方有多少数据构成一条消息,这是一种常见的方式。

顺便说一句,这段代码有一个严重的问题,就是一次读取整个文件。假设它很大,这段代码会崩溃。

接收器看起来像下面这样。这是一个基本的。

import io
def recv_exact(skt,count):
    buf = io.BytesIO()
    while count:
        data = skt.recv(count)
        if not data:
            return b"" # socket closed
        buf.write(data)
        count -= len(data)
    return buf.getvalue()

def recv_file(skt):
    data = recv_exact(skt,20)
    if not data:
        return b""
    file_size = int.from_bytes(data,"big")
    file_bytes = recv_exact(skt,file_size)
    return file_bytes