套接字被阻止将json对象从Java传输到Python

时间:2018-08-24 17:04:48

标签: java android python json sockets

我在使用Java-Python套接字时遇到问题。我的目标是通过套接字tcp将Java应用程序中的Json对象发送到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。问题是什么?问题似乎在in.readLine()。如果我删除该语句,则套接字可以正常工作。

2 个答案:

答案 0 :(得分:1)

您的Python代码正在等待Java端完成操作并发送EOF,然后再进行响应(这就是recv的意思,直到您得到一个空字节)。

您的Java代码正在等待Python端响应,然后再关闭套接字。

所以,他们俩都在等待对方。


删除readLine意味着Java代码不再等待任何内容,因此它在发送完成后立即挂在Python代码上,这确实使问题消失了,但是并没有解决。如果您确实需要回应,可以提供很多解决方案。


那么,他们应该怎么做?好吧,有几种不同的选择。

  • 使用成帧协议,其中Java端在每个消息之后发送“消息完成”定界符,或者在每个消息之前发送标头(例如消息的字节长度)。因此,Python代码可以读取直到收到完整的消息为止,而不是直到EOF为止。
    • 如果您以紧凑格式对JSON进行编码,除了可打印的ASCII转义符外,所有内容都应转义,则分隔符可以只是换行符(此时您使用JSONlines作为协议),Python代码可以使用{{1} },然后调用makefile而不是循环访问readline
  • 作弊并使用JSON,就好像它是框架协议一样。不是,但是只要您发送的唯一顶级值是对象和数组,它就可以工作。然后,每次接收后,Python代码都可以使用recv(请参阅raw_decode模块文档),直到成功为止。
  • 如果您只想发送一条消息,则只需从Java半关闭套接字(关闭写端),然后Python将获得其EOF并在仍打开的另一侧进行响应插座。 (这听起来似乎很骇人听闻,但这实际上是很普遍的-尽管HTTP 1.1使事情变得有些复杂,但这是Web浏览器传统上的工作方式。)

答案 1 :(得分:0)

您的回答不是一行,因为它似乎没有一行结尾。 这意味着它将readLine永远读下去。

尝试在响应中添加换行符,以使readLine感到满意:

resp = "Prova\n"