我正在使用python套接字与后端服务(B<->C(进行通信,如以下结构所示(:
spawn Popen
NodeJS server ------- Python Subprocess ------ backend process
A B C
每次启动套接字时,它都工作得很好 - 但是当我停止测试它时,几个小时后当我再次测试它时,它不会返回答案。
我听说可能存在一个问题:
如果客户端由于某种原因断开连接,您将获得 EOF(一个 空字符串(来自 conn.recv。然后您将写入并刷新一个空 字符串(零字节(到 p.stdin,这是一个无操作。您的子流程将 然后永远等待。
但是我该如何解决这个问题呢?
我改进了我的代码,但仍然无法正常工作。以下是代码:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, port))
p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
s.listen(10)
conn, addr = s.accept()
while(conn):
data = conn.recv(1024)
while(data):
if not data:
break
p.stdin.write(data)
p.stdin.flush()
result = p.stdout.readline()
conn.sendall(result)
break
conn.close()
conn, addr = s.accept()
s.close()
有什么改进代码的想法吗?谢谢。
程序的逻辑是:
while connected:
send request from network peer to backend
send reply from backend to network peer
它容易崩溃的原因是因为它假设一个网络读取返回一个请求。但是,对于网络流(即TCP(,无法保证数据边界。输入可以以一个数据包的形式到达,但也可以在多个网络数据包中到达,并且可能需要多次读取(或recvs(才能获得整个数据 - 即使另一端在一次网络写入中发送了它。
当不完整的请求发送到后端进行处理时,程序会等待回复,而后端仍会等待请求的其余部分。通信不同步,结果是死锁。
要修复它,两个程序都必须遵循通信协议规则。何时发送,发送什么以及何时接收。