我正在尝试将大型 numpy 数组从服务器多次传输到客户端(使用 while 循环)。但它只是挂着,什么都不做。 我正在使用 python 3.11 和 pickle 协议 5。
这是服务器:
import socket
import numpy as np
import pickle
import time
s = socket.socket()
print("Socket successfully created")
port = 12345
s.bind(('', port))
print("socket binded to %s" % (port))
s.listen(5)
print("socket is listening")
c, addr = s.accept()
print('Got connection from', addr)
try:
while True:
x = np.random.random([100, 100, 2])
data = pickle.dumps(x)
c.sendall(pickle.dumps(x))
ack = c.recv(1024)
if not ack:
break
except ConnectionResetError:
print('Connection reset by peer')
time.sleep(5)
finally:
c.close()
s.close()
这是客户 -
import socket
import numpy as np
import pickle
import time
s = socket.socket()
port = 12347
try:
s.connect(('127.0.0.1', port))
while True:
data = b""
chunk_size = 1024
while True:
chunk = s.recv(chunk_size)
if not chunk:
break
data += chunk
print(pickle.loads(data).nbytes)
# Send acknowledgment to the server
s.sendall(b'ACK')
except ConnectionResetError:
print('Connection reset by peer')
time.sleep(5)
finally:
s.close()
如果通信仅发生一次,即没有服务器和客户端的无限 while 循环,则此设置将起作用,但否则不起作用。 任何帮助将不胜感激!
客户端代码正在等待
if not chunk: break
处的流结束 (TCP FIN) 指示,以了解服务器何时完成发送,但在客户端发回回复之前,您永远不会从服务器发送信号。这会造成死锁,客户端和服务器都永远等待对方发送数据。我能想到的最简单的修复方法是在发送数据后关闭服务器连接的写入端,例如
# ... <previous code omitted> ...
while True:
c= socket.socket()
x = np.random.random([100, 100, 2])
data = pickle.dumps(x)
c.sendall(pickle.dumps(x))
c.shutdown(socket.SHUT_WR) # this is the new code
ack = c.recv(1024)
if not ack:
break
唯一的变化是添加了行
c.shutdown(socket.SHUT_WR)
。