繁体   English   中英

在 Python/Java 服务器/客户端之间发送对象

[英]Sending objects between Python/Java server/client

我有一个Python 客户端和一个Java 服务器 我希望客户端向服务器发送一个对象 如何实施?

如何还以另一种方式实现( Java 客户端 - Python 服务器)?

这是我使用 Python 服务器和 Java 客户端进行的尝试:

蟒蛇服务器端

import pickle
import socket

from simple_message import SimpleMessage

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 9999))
s.listen(1)

while True:
    print("Waiting for a message...")
    conn, addr = s.accept()
    data = conn.recv(4096)
    incoming_message = pickle.loads(data)
    conn.close()  # Close connection, not needed anymore
    print(SimpleMessage.get_payload(incoming_message))

它引用的对象(类SimpleMessage )定义如下:

#!/usr/bin/env python


class SimpleMessage:
    dest_address = str()
    message_type = int()
    payload = str()

    def __init__(self, dest_address, message_type, payload):
        self.dest_address = dest_address
        self.message_type = message_type
        self.payload = payload

    def get_payload(self):
        return self.payload

Java客户端

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

public class JavaClient {
    public static void main(String[] args) throws IOException {
        Socket sendingSocket = new Socket();
        sendingSocket.connect(new InetSocketAddress("127.0.0.1", 9999));
        OutputStream outputStream = sendingSocket.getOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
        SimpleMessage message = new SimpleMessage("127.0.0.1", 1, "Test message!");
        objectOutputStream.writeObject(message); // Write Message on socket
        sendingSocket.close();
    }
}

和类SimpleMessage

import java.io.Serializable;

public class SimpleMessage implements Serializable {
    private String destAddress;
    private Integer messageType;
    private String payload;

    public SimpleMessage(String destAddress, Integer messageType, String payload) {
        this.destAddress = destAddress;
        this.messageType = messageType;
        this.payload = payload;
    }
}

输出

这是我在Python 服务器端得到的输出:

Waiting for a message...
Traceback (most recent call last):
  File "python_server.py", line 16, in <module>
    incoming_message = pickle.loads(data)
_pickle.UnpicklingError: invalid load key, '\xac'.

这是我在Java 客户端得到的输出:

Exception in thread "main" java.net.SocketException: Broken pipe (Write failed)
    at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
    at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
    at java.base/java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1883)
    at java.base/java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1792)
    at java.base/java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1287)
    at java.base/java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1232)
    at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1428)
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1179)
    at java.base/java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1583)
    at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:352)

这是选择序列化格式的特定实例。

https://en.wikipedia.org/wiki/Comparison_of_data-serialization_formats

这是一个可能过于宽泛的话题,因此考虑到所有可能的格式,我将不提供冗长且可能多余的答案。

JSON 是一种很好且当前流行的格式,它可以帮助您入门,但将来也有可能在更多涉及的用例中发挥作用。 Python 和 Java 中有一些著名的库。

无论您选择什么,如果在小型原型或赋值之外有任何用途,定义显式模式为未来的工作奠定了良好的基础(例如,对 JSON 使用 JSON 模式)。

pickle与您的原始示例代码一样,是一种特定于 Python 的序列化格式。 因此,除非您在 Java 世界中对 Jython 之类的工具有特定用途,否则它不是通过网络与可以用另一种语言编写的服务进行通信的最佳选择。

您还应该考虑低级套接字是否是您用例的最佳选择,或者像 HTTP 这样的更高级别的网络库可能更适合。

您在这里所说的也称为系统中元素的解耦。

这为您在系统中更改语言和实现提供了很大的灵活性,这也是在微服务架构中不同后端服务相互通信时使用的方法。

常见的做法是选择一个双方相互传输的JSON协议:例如:

{
 fName: "David",
 lName: "Gold"
}

然后在两个元素之间对 GET 或 POST 数据进行 HTTP 调用。

通过这样做,您可以自由地更改每一端的实现(假设您发现用 JavaScript 编写客户端和用 R 编写服务器更好)。

只要双方继续使用相同的协议,他们对对方使用的实现是不可知的。

暂无
暂无

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

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