如何在python中通过TCP下载大量数据?

问题描述 投票:0回答:1

到目前为止,在我的项目中,我一直使用以下解决方案来下载数据。数据量很小,所以没有问题:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.0.10', 6100)
sock.connect(server_address)
sock.send(*** here is command to server***)
data = sock.recv(1024)
sock.close()

现在,我需要从服务器下载大量数据,结果发现我的解决方案只检索了其中的一部分。我读到问题可能是 TCP 数据包的最大大小。我尝试使用以下代码解决它:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.0.10', 6100)
sock.connect(server_address)
sock.send((*** here is command to server***)

data = b''
while True:
    try:
        chunk = sock.recv(1024)
    except Exception as e:
        print(e)
    if not chunk:
        chunk = str(repr(data.decode()))
        sock.close()
        break
    data += chunk
print(f"Received data: {data}")

该循环的工作原理是将数据流的连续部分添加到“data”。不幸的是,当数据完成后,脚本挂起。我做错了什么?

我应该提到我无法控制服务器。我只能通过请求从中获取现成的数据包。我无法控制它向我发送数据包的部分内容。一切都必须发生在我这边,即客户端。 数据包总是以“\x00”结尾我可以用它吗?

python tcp client-server
1个回答
0
投票

这是一个简单的基于套接字的客户端/服务器程序的示例。

这里我们使用哨兵(EOT)来表示所有数据已经传输完毕。显然,只有在保证重要数据不包含 EOT 字符的情况下才能做到这一点。 客户端将发送 5,000 字节。服务器将接收

最多

2,048 字节的数据块。 接收到的数据将被累积并打印总长度。该数字应与传输的数据大小相匹配。

注意事件的使用。这很重要,因为理论上客户端可能会在服务器侦听和接受连接之前尝试连接。

from socket import socket, AF_INET, SOCK_STREAM from threading import Thread, Event BUFSIZ = 2048 HOST_PORT = "localhost", 6667 EOT = b"\x04" def server(event): with socket(AF_INET, SOCK_STREAM) as s: s.bind(HOST_PORT) s.listen() event.set() c, _ = s.accept() all_data = b"" while data := c.recv(BUFSIZ): if data[-1] != ord(EOT): all_data += data else: all_data += data[:-1] break print(len(all_data)) if __name__ == "__main__": event = Event() (thread := Thread(target=server, args=(event,))).start() message = b"x" * 5000 event.wait() with socket(AF_INET, SOCK_STREAM) as s: s.connect(HOST_PORT) s.sendall(message+EOT) thread.join()

© www.soinside.com 2019 - 2024. All rights reserved.