Java 套接字传输

Java 套接字传输,java,sockets,vector,Java,Sockets,Vector,我有几个类同时运行,它们从服务器获取输入。两个都设置了插座 问题是,即使我在类之间传输相同的数据,但当数据到达时,它并不相同 以下是发送方法: private boolean transferBroadcastData() { boolean success = false; try { Vector<Client> clientsList =

我有几个类同时运行,它们从服务器获取输入。两个都设置了插座

问题是,即使我在类之间传输相同的数据,但当数据到达时,它并不相同

以下是发送方法:

        private boolean transferBroadcastData() {
            boolean success = false;

            try {           
                Vector<Client> clientsList =
                    onlineList.getClientsList();

                for (Client client : clientsList) {
                        ObjectOutputStream objectOutputStream =
                            client.getObjectOutputStream();
                            objectOutputStream.writeObject(clientsList);
                            objectOutputStream.flush();
                }


                success = true;

            } catch (Exception ioException) {
                ioException.printStackTrace();
            }

            return success;
        }
private boolean transferBroadcastData(){
布尔成功=假;
试试{
向量客户列表=
onlineList.getClientsList();
for(客户端:客户端列表){
ObjectOutputStream ObjectOutputStream=
client.getObjectOutputStream();
objectOutputStream.writeObject(客户端列表);
objectOutputStream.flush();
}
成功=真实;
}捕获(异常ioException){
ioException.printStackTrace();
}
回归成功;
}
以下是接收方法:

        while (true) {
                try {
                    Object object = objectInputStream.readObject();

                    if (object instanceof Vector<?>) {
                        String x = "I got it:\n";

                        Vector<Client> clients = (Vector<Client>) object;

                        for(Client c : clients) {
                            x += "\n" + c;
                        }

                        JOptionPane.showMessageDialog(ClientManager.this, x);

                        usersPanel.addClientsToList((Vector<Client>) object);
                    }

                    else if (object instanceof Message)
                        messagePanel.appendText((Message) object);


                } catch (ClassNotFoundException classNotFoundException) {
                    statusPanel.updateStatus("Error reading from socket");
                }
            }
while(true){
试一试{
Object Object=objectInputStream.readObject();
if(向量的对象实例){
String x=“我知道了:\n”;
向量客户端=(向量)对象;
用于(客户c:客户){
x+=“\n”+c;
}
showMessageDialog(ClientManager.this,x);
usersPanel.addClientsToList((Vector)对象);
}
else if(消息的对象实例)
messagePanel.appendText((Message)对象);
}捕获(ClassNotFoundException ClassNotFoundException){
statusPanel.updateStatus(“从套接字读取错误”);
}
}
当我在所有客户机上收到向量时,其中的元素是不同的。这不是我试图传递的向量的内容


我遗漏了什么?

问题可能与您使用序列化/ObjectOutputStream有关。序列化对象时,ObjectOutputStream会保留内部记录以“优化”序列化过程,因此,如果将同一对象序列化两次,它只会重复ID,假设对象未更改。例如,如果运行代码:

ObjectOutputStream oos = new ObjectOutputStream();
MyObject[] arr = new MyObject[]{myObject};
oos.write(myObject);
oos.write(arr);
ObjectOutputStream oos = new ObjectOutputStream();
oos.write(myObject);
myObject.setBaz(99999);
oos.write(myObject);
输出可能如下所示(注意,不是实际格式,只是一个示例):

请注意,数组将不会再次序列化对象,而只是已序列化版本的id。如果您有代码,请再进一步:

ObjectOutputStream oos = new ObjectOutputStream();
MyObject[] arr = new MyObject[]{myObject};
oos.write(myObject);
oos.write(arr);
ObjectOutputStream oos = new ObjectOutputStream();
oos.write(myObject);
myObject.setBaz(99999);
oos.write(myObject);
你最终会得到:

[[myObject;id=357;foo=bar;baz=36;]]
{id=357}
请注意,即使对象已更改,也只会序列化内部id。诀窍在于,在编写对象时,需要清除ObjectOutputStream的内部状态,这可以通过reset()完成。从javadocs:

重置将忽略任何 已写入流的对象。 状态被重置为与状态相同 新建ObjectOutputStream

因此,如果您使用上一个示例并添加重置:

ObjectOutputStream oos = new ObjectOutputStream();
oos.write(myObject);
myObject.setBaz(99999);
oos.reset();
oos.write(myObject);
您应获得以下预期行为的输出:

[[myObject;id=357;foo=bar;baz=36;]]
[[myObject;id=358;foo=bar;baz=99999;]]

需要注意的一点是,第二个序列化现在将被视为与原始序列化不同的对象。根据您传输数据的方式和内部关系,如果对象彼此共享引用,并且您希望保持这些关系,则必须小心不要过早重置流。

它不会改变。我试图将一个客户机向量转移到另一个ClientHandler,但是每次我在最先启动的ClientHandler上获得向量时,它们似乎都没有得到向量中最新的客户机。例如,如果我启动第一个ClientHandler,则收到的列表不会更新。似乎有多个大小不同的向量。向量的元素是由线程添加的。客户端类是什么样子的?我在尝试创建多线程客户端/服务器时遇到了相同的错误。在发送阵列之前,请尝试复制该阵列。我不知道为什么,但我认为它应该是有效的。对于那些想知道的人来说,客户机类是可序列化的,并且保存瞬态对象(套接字等)。