简体   繁体   中英

Send message from Java client to Python server using sockets and vice versa

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.

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.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM