我有一个 Java-Python 套接字的问题。我的目标是通过套接字 tcp 将 Json 对象从 java 应用程序发送到 python 脚本并接收响应,但套接字在 Json 发送后被阻塞。下面是我的代码:
try {
Socket socket = new Socket(dstAddress, dstPort);
is = new DataInputStream(socket.getInputStream());
os = new DataOutputStream(socket.getOutputStream());
PrintWriter pw = new PrintWriter(os, true);
pw.println(jsonObject.toString());
System.out.println("Send to the socket jsonObject.");
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String response = in.readLine();
System.out.println("Response: " + response);
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
在以下几行 python 代码中:
HOST = "192.168.1.101" #localhost
PORT = 7011
s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
while (1):
print("\n\nAttending for client.....\n\n")
conn, addr = s.accept()
print("Connected by: " , addr)
data = ""
while 1:
temp = conn.recv(1024).decode()
if not temp:
break
data = data + temp
print("JSON Received!!!!!")
imageJson = {}
imageJson = json.loads(data)
# responding to the client
response = DbImages[elem[0]]
resp = "Prova"
conn.send(resp.encode())
如果我终止 java 代码 (ctrl+C),则套接字从 block 中退出并且 json 到达 python。问题是什么?问题似乎出在.readLine() 中。如果我删除该语句,则套接字可以正常工作。
最佳答案
您的 Python 代码正在等待 Java 端完成并在响应之前发送 EOF(这就是 recv
的意思,直到您得到一个空字节)。
您的 Java 代码正在等待 Python 端响应,然后关闭套接字。
所以,他们都在等待对方。
删除 readLine
意味着 Java 代码不再等待任何东西,所以它在发送完成后立即卡在 Python 代码上,这确实使问题消失了——但它如果您确实需要回复,这不是一个很好的解决方案。
那么,他们应该做什么?嗯,有几个不同的选择。
- 使用框架协议(protocol),其中 Java 端要么在每条消息之后发送一个“消息完成”定界符,要么在每条消息之前发送一个 header (例如,消息的字节长度)。因此,Python 代码可以读取直到它有一个完整的消息,而不是直到 EOF。
- 如果您以紧凑格式对 JSON 进行编码,除了可打印的 ASCII 之外的所有内容都进行了转义,那么定界符可以只是一个换行符(此时您使用 JSONlines 作为协议(protocol)),Python 代码可以使用
makefile
并调用readline
而不是循环遍历recv
。
- 如果您以紧凑格式对 JSON 进行编码,除了可打印的 ASCII 之外的所有内容都进行了转义,那么定界符可以只是一个换行符(此时您使用 JSONlines 作为协议(protocol)),Python 代码可以使用
- 欺骗并使用 JSON,就好像它是一个框架协议(protocol)一样。它不是,但只要你发送的唯一顶级值是对象和数组,它就可以工作。然后 Python 代码可以在每次接收后使用
raw_decode
(参见json
模块文档)直到它成功。 - 如果你只打算发送一条消息,你可以从 Java 中半关闭套接字(关闭写入端),然后 Python 将获得它的 EOF 并在仍然打开的另一端响应 socket 。 (这听起来可能有些怪异,但实际上非常普遍——网络浏览器传统上就是这样工作的,尽管 HTTP 1.1 使事情变得有点复杂。)
关于java - 套接字在将 json 对象从 Java 传输到 Python 时被阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52008946/