Отправка объектов между Python / Java сервером / клиентом - PullRequest
2 голосов
/ 15 июня 2019

У меня есть клиент 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 CLIENT

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)

Ответы [ 2 ]

1 голос
/ 15 июня 2019

То, о чем вы здесь говорите, также известно как разделение элементов в системах.

Это дает вам большую гибкость для изменения языков и реализации в системе, и этот метод также используется, когда разные бэкэнд-сервисы взаимодействуют друг с другом в архитектуре микро-сервисов.

Обычный способ сделать это - выбрать протокол JSON, который обе стороны передают между собой: Например:

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

А затем сделать HTTP-вызовы для получения или получения данных между вашими двумя элементами.

Таким образом, вы можете свободно изменять реализацию на каждой стороне (скажем, вы обнаружите, что вам лучше написать свой клиент на JavaScript, а сервер на R).

Пока обе стороны работают с одним и тем же протоколом, они не зависят от реализации, которую использует другая сторона.

1 голос
/ 15 июня 2019

Это конкретный пример выбора формата сериализации.

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

Это потенциально заурядная тема, поэтому я воздержусь от длинного и, возможно, избыточного ответа, учитывая всеВозможные форматы.

JSON - это хороший и модный в настоящее время формат, который поможет вам начать работу, но в будущем он также будет хорошо работать с более сложными вариантами использования.В Python и Java есть хорошо известные библиотеки.

Независимо от того, что вы выберете, если есть какое-либо использование вне небольшого прототипа или назначения, определение явной схемы закладывает хорошую основу для будущей работы (например, с использованием JSON).схема для JSON).

pickle, как и в вашем исходном примере кода, является специфичным для Python форматом сериализации.Поэтому, если у вас нет особого использования такого инструмента, как Jython, в вашем мире Java, он не является отличным выбором для связи по сети со службой, которая может быть написана на другом языке.

Вы также должны рассмотреть, является ли низкийГнезда уровня являются лучшим выбором для вашего случая использования, или сетевая библиотека более высокого уровня, такая как HTTP, может быть более подходящей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...