首页 > 解决方案 > Python文件传输(tcp套接字),网络慢的问题

问题描述

我使用 Tor 和 socks 设置了一个安全套接字,但是在发送大量数据时遇到了问题

发件人:

socket.send(message.encode())

接收者:

chunks = []

while 1:
    part = connection.recv(4096)
    chunks.append(part.decode())

    if len(part) < 4096:
        break

response = "".join(chunks)

由于网络速度在循环中不一致,我并不总是填充 4096b 缓冲区,因此循环中断并且我没有收到完整的数据。

降低缓冲区大小似乎不是一个选项,因为“数据包”大小有时可能低至 20b

标签: pythonpython-3.xtcpproxyfile-transfer

解决方案


尝试使用结构首先将传入数据的长度传递给接收器,“导入结构”。这样接收端就知道要接收多少数据。在这个示例中,字节是通过套接字发送的,这里的示例我从我的 github 上传 github.com/nsk89/netcrypt 中借用以供参考,并从发送函数中删除加密步骤以及发送序列化字典。

编辑我还应该澄清,当您通过套接字发送数据时,特别是如果您发送多条消息,它们都作为一条长消息位于流中。并非每条消息的长度都是 4096 字节。如果一个长度为 2048,下一个为 4096,并且您在缓冲区中收到 4096,您将收到第一条消息加上下一条消息的一半,或者完全挂起等待更多不存在的数据。

data_to_send = struct.pack('>I', len(data_to_send)) + data_to_send # pack the length of data in the first four bytes of data stream, >I indicates internet byte order

    socket_object.sendall(data_to_send)  # transport data



def recv_message(socket_object):
    raw_msg_length = recv_all(socket_object, 4)  # receive first 4 bytes of data in stream
    if not raw_msg_length:
        return None

    # unpack first 4 bytes using network byte order to retrieve incoming message length
    msg_length = struct.unpack('>I', raw_msg_length)[0]

    return recv_all(socket_object, msg_length)  # recv rest of stream up to message length

def recv_all(socket_object, num_bytes):
    data = b''
    while len(data) < num_bytes:  # while amount of data recv is less than message length passed
        packet = socket_object.recv(num_bytes - len(data))  # recv remaining bytes/message
        if not packet:
            return None
        data += packet
    return data

推荐阅读