java - 套接字在将 json 对象从 Java 传输到 Python 时被阻塞

标签 java android python json sockets

我有一个 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,就好像它是一个框架协议(protocol)一样。它不是,但只要你发送的唯一顶级值是对象和数组,它就可以工作。然后 Python 代码可以在每次接收后使用 raw_decode(参见 json 模块文档)直到它成功。
  • 如果你只打算发送一条消息,你可以从 Java 中半关闭套接字(关闭写入端),然后 Python 将获得它的 EOF 并在仍然打开的另一端响应 socket 。 (这听起来可能有些怪异,但实际上非常普遍——网络浏览器传统上就是这样工作的,尽管 HTTP 1.1 使事情变得有点复杂。)

关于java - 套接字在将 json 对象从 Java 传输到 Python 时被阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52008946/

相关文章:

java - 使用反射时如何检查字段是否有注释

java - Quartz调度器可以用来模拟吗?

Android Chronometer 自己的实现

java - 在RelativeLayout上检测多点触摸

python - 链表类 __str__ 函数

java - JPA Select 查询不返回一个字母单词的结果

android - Android中哪种类型的服务会占用更多的系统资源

python - 如何从 .csv 文件加载数据而不导入 .csv 模块/库

python - 从 python 中的一行中拉出特定的子字符串

java - 将 Java POJO 转换为 PactDslJsonBody