Передача точно таких же объектных сокетов

#java #sockets #serialization

#java #Сокеты #Сериализация

Вопрос:

Я задал еще один вопрос

У меня есть сервер классов:

 package server;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;
import javax.swing.DefaultListModel;
import objects.Player;

public class Servidor implements Runnable, Observer {

int puerto;
public DefaultListModel<Player> players = new DefaultListModel<>();
public ArrayList<Socket> clients = new ArrayList<>();

public static Send m;

public Servidor(int puerto, Send m) {
    this.m = m;
    this.m.addObserver(this);
    this.puerto = puerto;
    System.out.println(this.m   " from the server")
}

@Override
public void run() {
    ServerSocket servidor = null;
    Socket sc = null;
    ObjectOutputStream output;

    try {
        servidor = new ServerSocket(puerto);
        System.out.println("Server Started");

        while (true) {
            sc = servidor.accept();
            System.out.println("New Cliente");

            output = new ObjectOutputStream(sc.getOutputStream());

            output.writeObject(m);
            clientes.add(sc);
        }
    } catch (IOException ex) {
    }
}

public void Send_Players() throws IOException {
    for (Socket sc : clients) {
        ObjectOutputStream output = new ObjectOutputStream(sc.getOutputStream());

        output.writeObject(players);
    }
}

@Override
public void update(Observable o, Object arg) {
    //Stuff
}
  

Тогда у меня есть свой клиентский класс:

 package server;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import objects.Player;

public class Client extends Observable implements Runnable {

String host;
int puerto;
Socket sc;

public Client(int purto, String host) {
    this.puerto = purto;
    this.host = host;

    try {
        sc = new Socket(host, puerto);
    } catch (IOException ex) {
    }
}

@Override
public void run() {
    DataInputStream in;
    ObjectInputStream input = null;
    DefaultListModel<Player> players = new DefaultListModel<>();
    try {
        in = new DataInputStream(sc.getInputStream());
        input = new ObjectInputStream(in);
    } catch (IOException ex) {
    }
    while (true) {
        Object objeto = null;
        try {
            objeto = input.readObject();
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (objeto != null) {
            System.out.println("Is: "   objeto.getClass().getName());
            if (objeto instanceof DefaultListModel) {

                players = (DefaultListModel<Player>) objeto;

                this.setChanged();
                this.notifyObservers(players);
                this.clearChanged();
            } else {
                Send m = (Send) objeto;

                this.setChanged();
                this.notifyObservers(m);
                this.clearChanged();
            }
        }
    }
}
}
  

А также класс отправки:

 package server;

import java.io.Serializable;
import java.util.Observable;

public class Send extends Observable implements Serializable{

private static final long serialVersionUID = 1L;

public void Send_(Object arg){
    this.setChanged();
    this.notifyObservers(arg);
    this.clearChanged();
}
}
  

Теперь я объясню, как это работает:

  1. Когда я создаю сервер, я добавляю его в качестве наблюдателя класса Send

  2. Когда я создаю нового клиента, сервер обнаруживает его

  3. Когда пришел новый клиент. Он отправляет объект типа Send.

  4. В клиентском классе он обнаруживает с помощью observable, что что-то пришло, и уведомляет класс с именем Main.

  5. Когда наблюдатель класса Main получает уведомление, он делает это:

     this.m = (Send) arg;
    System.out.println(this.m   " from the class Main");
      

Но класс, отправляемый с сервера, не равен классу, отправляемому из класса Main
Но мне нужно, чтобы они были равны, чтобы я мог использовать метод Send_ в классе send для уведомления наблюдателя

Вывод: сервер.Отправка @6576a5d6 с сервера запускает сервер новых клиентов: server.Отправьте сервер sipili.Отправить @156ecdb0 с клиента

и мне нужно, чтобы первая строка вывода (объект 1) должна совпадать с последней строкой вывода

Примечание: я думаю, что это как-то связано с сериализованной версией

Комментарии:

1. В чем здесь вопрос? Что вы подразумеваете под «класс не равен»? Вы получаете исключение? Неожиданное поведение?

2. нет, я говорю так, как будто класс не является одним и тем же экземпляром, например: статическая переменная всегда одна и та же, но нестатическая переменная отличается при создании новой

3. Когда вы делаете это: ExampleClass class = новый класс, вы создали новый класс. когда вы печатаете класс, например, так: System.out.println(class); , Он печатает что-то вроде этого ExampleClass@8483de6 конечные номера присутствуют, потому что вы можете создавать несколько классов этого типа, поэтому они могут быть разными, и каждый из них использует свои собственные переменные. Когда я создаю его из своего серверного класса, это выглядит так: Send@138nf5, но когда я использую ObjectOutputStream, он не отправляет это: Send@138nf5, он отправляет новый класс, поэтому я не могу использовать переменные из этого класса

4. Нет. Пожалуйста, исправьте свою терминологию. У вас есть путаница между классами и объектами (или экземплярами). Когда вы это делаете new ExampleClass() , вы создаете новый объект типа ExampleClass . ObjectOutputStream отправляет то, что вы говорите ему отправить, но оно принимается как новый объект, если только оно уже не было отправлено и вы не использовали reset() или writeUnshared() , и в этом случае он возвращает вам существующий объект, но в этом случае, конечно, без каких-либо изменений, которые могли быть внесены на отправляющей стороне. Неясно, что вы на самом деле спрашиваете здесь.

5. Да, я ссылаюсь на это как на объект. И нет, когда я отправляю объект, он создает новый, откуда я это знаю? Просто используя System.out.println(), и он печатает 2 разных объекта в 2 разных классах

Ответ №1:

К сожалению, вы не можете, в https://docs.oracle.com/javase/8/docs/api/java/io/ObjectInputStream.html в нем говорится, что способ, которым это работает, заключается в том, чтобы.

  1. Отправка типа объекта.
  2. Создание нового объекта.
  3. Замена значений на те, которые находятся в вашем другом классе.

Таким образом, невозможно сделать точную копию.