如何使用 Java 客户端和 Python 服务器通过套接字创建 IPC?

爵士芯片

我试图让两个进程通过本地套接字进行通信:一个 Python服务器和一个 Java客户端我想在两者之间传递的数据由大小可变Protobuf对象字节组成我希望连接保持打开状态并一直使用到程序结束,因为我传递了很多需要处理的对象。

因为 Protobuf 对象的大小可变,所以我在发送包含该对象的真实消息/响应之前发送消息/响应的大小。

目前,我在 Python 端使用socketserver库中的 TCPServer 我实现了以下处理程序:

class MyTCPHandler(socketserver.BaseRequestHandler):
    """
    The request handler class for our server.

    It is instantiated once per connection to the server, and must
    override the handle() method to implement communication to the
    client.
    """

    def recv_all(self, n):
        # Helper function to recv n bytes or return None if EOF is hit
        data = b''
        while len(data) < n:
            packet = self.request.recv(n - len(data))
            if not packet:
                return None
            data += packet
        return data

    def handle(self):
        logger.debug("Beginning of handle cycle for client: {}.".format(self.client_address))

        while True:
            if True: # please disregard this if condition
                # Receive 4 bytes (1 int) denoting the size of the message
                data_length_bytes: bytes = self.recv_all(4)
                logger.debug('Received data_length: {}'.format(data_length_bytes))

                # If recv read an empty request b'', then client has closed the connection
                if not data_length_bytes:
                    break

                data_length: int = int.from_bytes(data_length_bytes.strip(), byteorder='big')
                data: bytes = self.recv_all(data_length).strip()

                response: bytes = data.upper()

                # Send length of response first
                self.request.sendall(len(response).to_bytes(4, byteorder='big'))
                # Send response
                self.request.sendall(response)

                logger.debug(
                    'Sent response to: {}. Size of response: {} bytes. Response: {}.'.format(self.client_address,
                                                                                             len(response),
                                                                                             response))


        logger.debug("End of handle cycle for client: {}.".format(self.client_address))

以及以下客户端:

class SocketClient
{
    private static Socket socket;
    private int port;
    private DataOutputStream out;
    private DataInputStream in;

    SocketClient(int port)
    {
        this.port = port;
        this.createSocket();
    }

    private void createSocket() {
        InetAddress address;
        try {
            address = InetAddress.getByName("localhost");
            socket = new Socket(address, port);
            this.out = new DataOutputStream(socket.getOutputStream());
            this.in = new DataInputStream(socket.getInputStream());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    byte[] sendMessageAndReceiveResponse(byte[] messageToSend){
        try {
            if(true) {  // again, please disregard this condition
                //Send the size of the message to the server
                this.out.writeInt(messageToSend.length);
                out.flush();

                this.out.write(messageToSend);
                out.flush();

                //Get the response message from the server
                int length = in.readInt();                    // read length of incoming message

                byte[] buffer = null;
                if(length>=0) {
                    buffer = new byte[length];
                    in.readFully(buffer, 0, buffer.length); // read the message
                }

                return buffer;
            }
        }
        catch (ConnectException exception) {
            System.out.println("ATTENTION! Could not connect to socket. Nothing was retrieved from the Python module.");
            exception.printStackTrace();
            return null;
        }
        catch (Exception exception)
        {
            exception.printStackTrace();
            return null;
        }
    }

    void close(){
        //Closing the socket
        try
        {
            in.close();
            out.close();
            socket.close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

我在启动 Python 服务器后运行以下实验:

        SocketClient socketClient = new SocketClient(5000);

        byte[] response;

        // Case 1
        response = socketClient.sendMessageAndReceiveResponse("12345678".getBytes());
        System.out.println(new String(response));

        // Case 2
        response = socketClient.sendMessageAndReceiveResponse("123456781".getBytes());
        System.out.println(new String(response));

        // Case 3
        response = socketClient.sendMessageAndReceiveResponse("12345678123456781".getBytes());
        System.out.println(new String(response));


        socketClient.close();

案例 1 和案例 3 运行良好。但是,当我运行case 2 时,在 Python 服务器端,我得到以下日志:

DEBUG -- [handle()] Received data_length: b'\x00\x00\x00\t' # The '\t' shouldn't be here. A '\x09' should.

然后服务器抛出异常并退出连接。每个 8 < 长度 < 14 的字符串都会发生这种情况。我做错了什么,有没有更简单的方法来实现我想要的?

爵士芯片

我想出了为什么我在处理 8 < 长度 < 14 的消息时遇到问题。

\t当长度等于 9 时,我得到了字符。我注意到如果我将长度更改为 10,它会变成\n. 到 13, \r. 我意识到没有任何\t神奇的出现。Python 出于某种原因转换\x09\t,因为水平制表符\t的 ASCII 码等于 9!

当我strip()在这一行中应用该函数时:

data_length: int = int.from_bytes(data_length_bytes.strip(), byteorder='big')

,Python 删除了我的\t,实际上是我的\x09. 我的问题是剥离之前记录该值,所以我花了很长时间才弄清楚我的错误。

因此,解决方案是根本不使用strip(). 我在这里留下我当前的工作代码(至少对于我的测试),供某人使用:

Python服务器处理程序:

class MyTCPHandler(socketserver.BaseRequestHandler):
    """
    The request handler class for our server.

    It is instantiated once per connection to the server, and must
    override the handle() method to implement communication to the
    client.
    """

    def recv_all(self, n):
        # Helper function to recv n bytes or return None if EOF is hit
        data = b''
        while len(data) < n:
            packet = self.request.recv(n - len(data))
            if not packet:
                return None
            data += packet
        return data

    def handle(self):
        while True:
            data_length_bytes: bytes = self.recv_all(4)

            # If recv read an empty request b'', then client has closed the connection
            if not data_length_bytes:
                break

            # DON'T DO strip() ON THE DATA_LENGTH PACKET. It might delete what Python thinks is whitespace but
            # it actually is a byte that makes part of the integer.
            data_length: int = int.from_bytes(data_length_bytes, byteorder='big')

            # Don't do strip() on data either (be sure to check if there is some error if you do use)
            data: bytes = self.recv_all(data_length)

            response: bytes = data.upper()

            self.request.sendall(len(response).to_bytes(4, byteorder='big'))
            self.request.sendall(response)

Java 客户端保持不变,但没有if(true)我出于调试原因使用的条件。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Java套接字:一台服务器和多个客户端

来自分类Dev

如何在Python客户端和C ++服务器上使用套接字

来自分类Dev

Python套接字服务器/客户端编程

来自分类Dev

使用Python服务器和Android客户端进行套接字编程

来自分类Dev

尝试使用Thrift的TFileTransport和TFileProcessor与Java服务器进行Python客户端对话

来自分类Dev

使用Java中的套接字将文件从服务器下载到客户端

来自分类Dev

Python套接字服务器通过使用令牌进行客户端身份验证

来自分类Dev

使用Python使客户端套接字等待服务器套接字

来自分类Dev

套接字服务器和套接字客户端Java-从位于不同计算机上的客户端检测服务器

来自分类Dev

如何使用Java / Java脚本从服务器发送图像到客户端web套接字?

来自分类Dev

如何使用grpc在python服务器和php客户端之间进行通信?

来自分类Dev

套接字Python服务器和Java-Android Studio中的客户端,其中Java无法连接到python服务器

来自分类Dev

如何让客户端套接字继续在python中侦听服务器?

来自分类Dev

在python中关闭服务器后,如何让客户端套接字继续监听服务器?

来自分类Dev

使用python和Typscript连接两个套接字(客户端和服务器)

来自分类Dev

使用python套接字将Txt文件从客户端发送到服务器

来自分类Dev

使用Python服务器和Android客户端进行套接字编程

来自分类Dev

通过ActionScript服务器和Java客户端之间的套接字发送对象

来自分类Dev

如何使用客户端套接字作为服务器套接字python

来自分类Dev

如何使用Java中的套接字从服务器向特定客户端发送字符串消息?

来自分类Dev

如何使Java客户端使用套接字连接到不在我的计算机上的服务器?

来自分类Dev

Server(Python)-使用套接字的客户端(Java)通信

来自分类Dev

Java客户端/服务器套接字问题

来自分类Dev

套接字服务器和套接字客户端Java-从位于不同计算机上的客户端检测服务器

来自分类Dev

如何使用PHP和Apache Web服务器正确调用Python Pyro客户端?

来自分类Dev

如何使用url将python套接字客户端连接到服务器套接字?

来自分类Dev

Python 如何使套接字服务器使用客户端内置的命令

来自分类Dev

如何使用 Spock 对 Java 套接字服务器/客户端对进行单元测试?

来自分类Dev

Java TCP 客户端/服务器套接字

Related 相关文章

  1. 1

    Java套接字:一台服务器和多个客户端

  2. 2

    如何在Python客户端和C ++服务器上使用套接字

  3. 3

    Python套接字服务器/客户端编程

  4. 4

    使用Python服务器和Android客户端进行套接字编程

  5. 5

    尝试使用Thrift的TFileTransport和TFileProcessor与Java服务器进行Python客户端对话

  6. 6

    使用Java中的套接字将文件从服务器下载到客户端

  7. 7

    Python套接字服务器通过使用令牌进行客户端身份验证

  8. 8

    使用Python使客户端套接字等待服务器套接字

  9. 9

    套接字服务器和套接字客户端Java-从位于不同计算机上的客户端检测服务器

  10. 10

    如何使用Java / Java脚本从服务器发送图像到客户端web套接字?

  11. 11

    如何使用grpc在python服务器和php客户端之间进行通信?

  12. 12

    套接字Python服务器和Java-Android Studio中的客户端,其中Java无法连接到python服务器

  13. 13

    如何让客户端套接字继续在python中侦听服务器?

  14. 14

    在python中关闭服务器后,如何让客户端套接字继续监听服务器?

  15. 15

    使用python和Typscript连接两个套接字(客户端和服务器)

  16. 16

    使用python套接字将Txt文件从客户端发送到服务器

  17. 17

    使用Python服务器和Android客户端进行套接字编程

  18. 18

    通过ActionScript服务器和Java客户端之间的套接字发送对象

  19. 19

    如何使用客户端套接字作为服务器套接字python

  20. 20

    如何使用Java中的套接字从服务器向特定客户端发送字符串消息?

  21. 21

    如何使Java客户端使用套接字连接到不在我的计算机上的服务器?

  22. 22

    Server(Python)-使用套接字的客户端(Java)通信

  23. 23

    Java客户端/服务器套接字问题

  24. 24

    套接字服务器和套接字客户端Java-从位于不同计算机上的客户端检测服务器

  25. 25

    如何使用PHP和Apache Web服务器正确调用Python Pyro客户端?

  26. 26

    如何使用url将python套接字客户端连接到服务器套接字?

  27. 27

    Python 如何使套接字服务器使用客户端内置的命令

  28. 28

    如何使用 Spock 对 Java 套接字服务器/客户端对进行单元测试?

  29. 29

    Java TCP 客户端/服务器套接字

热门标签

归档