0

I am trying to send receive data using a Python server and a Java client. First, Java sends a JSON in string to Python Server. After the string received, Python server will send a JSON back to the client. After the client receives the JSON from the server, it again sends a JSON in string to server. (Client sends the same message all the time) This is a recursive process.

ISSUE: After when I execute both Python server and Java, Python server receives the message sent by the Java Client and it sent back the JSON. But in the client side, the message sent by the server didnt receive.

Server.py

import socket
import threading
import json
import numpy

HEADER_INITIAL = 25

PORT = 1234
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'

    def handle_client(self, conn, addr):
        print(f"[NEW CONNECTION] {addr} connected.")

        connected = True
        while connected:
            msg = conn.recv(HEADER_INITIAL).decode(FORMAT)
            if msg:
                print("[DATA] RECEIVED"+ str(msg))
       
                x = {
                      "Sentence": "This is a value"
                    }
                y = json.dumps(x)
                conn.send(y.encode(FORMAT))
                conn.send("\n".encode(FORMAT));
        conn.close()        

Client.java

    try (Socket socket = new Socket(Address, Port)) {

            InputStream input = socket.getInputStream();
            InputStreamReader reader = new InputStreamReader(input);

            OutputStream output = socket.getOutputStream();
            PrintWriter writer = new PrintWriter(output, true);


            int  character;
            StringBuilder data = new StringBuilder();

            while(true){
                Thread.sleep(4000);
                String strJson = "{'message':'Hello World'}";
                JSONObject jsonObj = new JSONObject(strJson);

                writer.println(jsonObj.toString());
                while((character = reader.read()) != -1) {
                    data.append((char) character);
                }
                System.out.println(data);

            }
        } catch (UnknownHostException ex) {
            System.out.println("Server not found: " + ex.getMessage());
        } catch (IOException ex) {
            System.out.println("I/O error: " + ex.getMessage());
     }

UPDATE Here is the debug output. I first started the server and then started client. Initially server receives the {'message':'Hello World'} value which is sent by the client and the server sends back the value of the x variable to the client. Then the server receives nothing from the client, but the client prints the value of x continuously.( System.out.println(data);) I tried to send dynamic values from the server to client, but the client prints only the value which is sent by the server in the first time.

1 Answer 1

1
+50

You don't provide any debugging output so it's difficult to be 100% sure this is the entire cause. However, it seems pretty evident that this section of your client code isn't correct:

            while((character = reader.read()) != -1) {
                data.append((char) character);
            }
            System.out.println(data);

The server is holding the connection open forever (nothing ever sets connected to false). And so in the loop above, the character returned by reader.read will never be -1 because -1 is only returned at "end of stream". End of stream will only occur when the server closes its socket -- or is otherwise disconnected.

You should add a check for the newline to break out of the read loop:

                if (character == '\n')
                     break; 

or you could add it to the while condition:

           while ((character = reader.read()) != -1 && character != '\n') {
                 ...

Your code overall lacks appropriate handling of possible exceptional conditions. For example, if the client disconnects, your server will never exit its loop. It will call recv, get back an empty string (signifying "end of file" on the connection), and so will correctly bypass sending a response, but it will then simply go back and execute recv again, get an empty string again, and so forth forever.

Also, your python code makes the implicit assumption that the recv returns exactly the single string that was sent by the client, which is not guaranteed. If the client sends a 20 character string for example, it's possible that the first server recv call returns the first 10 characters, and the next call returns the rest.

(In practice, given the sleep in the client side code, that's unlikely to be a problem in this snippet of code, but one should program defensively because in a real production program, there will inevitably be a race or edge case that will do exactly this and it will cause the client and server to get out of sync and be difficult to debug.)

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much for the clarrification. I have updated the question by adding the debug information. Yeah my code lacks error handling, I need to apply appropriate exceptions. I have added the checking new line to the while condition as you mentioned in your post, but the result is same :( Server receives the message from client in the first time only, the result is ent to the client and the client prints the value sent by the server continously.
Suggestions: (1) in the client, after you println, re-initialize data to a null string. (2) in the client, following your while loop, print the value of character so as to determine why the loop ended. In general, print/println is your friend. Use it as often as necessary to debug. You can remove excess prints later once things are working. You should be able to insert step-by-step prints at every point on both sides. This is what debugging is all about: eventually you will be able to narrow it down to a single statement or operation.
Hello! It worked!!! I have done following modifications; 01) As you said, I re-initialized the data variable to a null string. Then no the same value printing issue stoppped. 02) Then I printed the characters and there I noted that there is no newline character in the message sent by the server. So I changed the line y = json.dumps(x) in the server to y = json.dumps(x) + '\n' and removed conn.send("\n".encode(FORMAT)); Then it works! Thank you very much for your support!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.