Блокировка сокета при передаче объекта json из Java в Python - PullRequest
0 голосов
/ 24 августа 2018

У меня проблема с сокетом Java-Python.Моя цель - отправить объект Json из java-приложения в скрипт python через сокет tcp и получить ответ, но сокет заблокирован после отправки 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), сокет выхода из блокаи json прибывают на питон.В чем проблема?Проблема, кажется, в .readLine ().Если я удалю это утверждение, сокет будет работать без блоков.

Ответы [ 2 ]

0 голосов
/ 24 августа 2018

Ваш код Python ожидает завершения на стороне Java и отправки EOF, прежде чем ответить (это то, что означает recv, пока вы не получите пустые байты).

Ваш код Java ждет ответа от стороны Python, прежде чем закрывать сокет.

Итак, они оба ждут друг друга.


Удаление readLine означает, что Java-код больше не ждет ничего, поэтому он просто зависает на коде Python, как только завершает отправку, что устраняет проблему, но это не так решение, если вам действительно нужен ответ.


Итак, что они должны делать? Ну, есть несколько разных вариантов.

  • Используйте протокол в рамке, где сторона Java либо отправляет разделитель «готово к выполнению сообщения» после каждого сообщения, либо отправляет заголовок (например, с длиной байта сообщения) перед каждым. Итак, код Python может читать, пока не получит полное сообщение, а не до EOF.
    • Если вы кодируете свой JSON в компактном формате, используя все, кроме печатного ASCII, тогда разделителем может быть просто новая строка (в этот момент вы используете JSONlines в качестве протокола), а код Python может использовать makefile на сокет и вызов readline вместо циклического перебора recv.
  • Читайте и используйте JSON, как если бы это был протокол в рамке. Это не так, но пока единственными значениями верхнего уровня, которые вы когда-либо отправляете, являются объекты и массивы, это работает. Затем код Python может использовать raw_decode (см. Документацию к модулю json) после каждого получения до тех пор, пока не получится.
  • Если вы собираетесь отправлять только одно сообщение, вы можете просто отключить сокет (закрыть конец записи) из Java наполовину, и тогда Python получит свой EOF и ответит на все еще открытой другой стороне розетка. (Это может показаться странным, но на самом деле это совершенно нормально - так традиционно работают веб-браузеры, хотя HTTP 1.1 усложнил ситуацию.)
0 голосов
/ 24 августа 2018

Ваш ответ не является строкой, так как, похоже, не содержит окончания строки. Это означает, что readLine будет читать вечно.

Попробуйте добавить новую строку в свой ответ, чтобы сделать readLine счастливым:

resp = "Prova\n"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...