简体   繁体   English

使用 sockets 将消息从 Java 客户端发送到 Python 服务器,反之亦然

[英]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.我正在尝试使用 Python 服务器和 Java 客户端发送接收数据。 First, Java sends a JSON in string to Python Server.首先,Java 将字符串中的 JSON 发送到 Python 服务器。 After the string received, Python server will send a JSON back to the client.收到字符串后,Python 服务器将发送 JSON 回客户端。 After the client receives the JSON from the server, it again sends a JSON in string to server.客户端从服务器收到 JSON 后,再次向服务器发送 JSON 字符串。 (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. 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服务器.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客户端.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.更新这里是调试 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.最初,服务器接收客户端发送的{'message':'Hello World'}值,然后服务器将x变量的值发送回客户端。 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.然后服务器从客户端什么也没收到,但客户端连续打印x的值。( System.out.println(data); )我试图从服务器向客户端发送动态值,但客户端只打印由服务器在第一时间发送。

You don't provide any debugging output so it's difficult to be 100% sure this is the entire cause.您没有提供任何调试 output 所以很难 100% 确定这是全部原因。 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).服务器永远保持connected打开(没有任何东西设置为 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".所以在上面的循环中, reader.read返回的字符永远不会是-1 ,因为-1只在“流结束”时返回。 End of stream will only occur when the server closes its socket -- or is otherwise disconnected. stream 的结束只会在服务器关闭其套接字或以其他方式断开连接时发生。

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 条件:

           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.它将调用recv ,返回一个空字符串(表示连接上的“文件结束”),因此将正确绕过发送响应,但它会简单地返回 go 并再次执行recv ,再次获取一个空字符串,然后以此类推。

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.此外,您的 python 代码隐含假设recv准确返回客户端发送的单个字符串,这不能保证。 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.例如,如果客户端发送一个 20 个字符的字符串,那么第一个服务器recv调用可能返回前 10 个字符,而下一个调用返回 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.) (在实践中,考虑到客户端代码中的休眠,这在这段代码中不太可能成为问题,但是应该进行防御性编程,因为在真正的生产程序中,不可避免地会出现竞争或边缘情况。这会导致客户端和服务器不同步并且难以调试。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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