【问题标题】:Transfer Exact Same Object Sockets传输完全相同的对象套接字
【发布时间】:2021-01-14 14:51:18
【问题描述】:

我带来了另一个问题

我有一个班级服务器:

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();
            }
        }
    }
}
}

还有 Send 类:

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");
    

但是来自 Server 的类 Send 不等于来自 Main 类的 Send 但我需要它们相等,这样我才能使用类 send 中的 Send_ 方法来通知观察者

输出: server.Send@6576a5d6 从服务器 服务器启动 新客户 Es: server.Send 西皮里 server.Send@156ecdb0 从客户端

我需要输出的第一行(对象 1) 需要和输出的最后一行一样

注意:我认为这与序列化版本有关

【问题讨论】:

  • 这里的问题是什么?你所说的“阶级不平等”是什么意思?你有例外吗?意外行为?
  • 不,我说类不是同一个实例,例如:静态变量总是相同的,但是当你创建一个新变量时非静态变量是不同的
  • 当您执行此操作时:ExampleClass class= new Class,您创建了一个新类。当您打印该类时,如下所示: System.out.println(class);,它打印出类似这样的内容 ExampleClass@8483de6 结束编号在那里,因为您可以创建该类型的多个类,因此它们可以是不同的并且每个使用他们自己的变量。当我从我的服务器类创建它时,它是这样的:Send@138nf5,但是当我使用 ObjectOutputStream 它不发送这个:Send@138nf5,它发送一个新类,所以我不能使用该类中的变量
  • 没有。请更正您的术语。您在类和对象(或实例)之间存在最终混淆。当您执行new ExampleClass() 时,您将创建一个ExampleClass 类型的新objectObjectOutputStream 发送您告诉它发送的内容,但它作为一个新对象接收,除非它已经发送并且您没有使用reset()writeUnshared(),在这种情况下它会将现有对象返回给您,但在这种情况下,当然不会在发送端进行任何更改。不清楚您在这里真正要问的是什么。
  • 是的,我将其称为对象。不,当我发送对象时,它会创建一个新对象,我怎么知道呢?通过简单地使用 System.out.println(),它会在 2 个不同的类中打印 2 个不同的对象

标签: java sockets serialization


【解决方案1】:

很遗憾你不能,在https://docs.oracle.com/javase/8/docs/api/java/io/ObjectInputStream.html 它说它的工作方式是通过。

  1. 发送对象类型。
  2. 创建新对象。
  3. 将值替换为其他类中的值。

所以不可能完全复制。

【讨论】:

    猜你喜欢
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 2012-02-08
    相关资源
    最近更新 更多