在Python/Java服务器/clien之间发送对象

2024-09-28 05:18:51 发布

您现在位置:Python中文网/ 问答频道 /正文

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

如何实现另一种方法(Java客户机-Python服务器)?你知道吗

下面是我对Python服务器和Java客户端的一个尝试:

PYTHON服务器端

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)

Tags: ioimportself客户端messagebasestringnet
2条回答

这是选择序列化格式的特定实例。你知道吗

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"
}

然后进行HTTP调用以获取或发布两个元素之间的数据。你知道吗

通过这样做,您可以随意更改每一方的实现(假设您发现最好用JavaScript编写客户端,用R编写服务器)。你知道吗

只要双方继续使用相同的协议,他们就不知道对方使用的实现。你知道吗

相关问题 更多 >

    热门问题