简体   繁体   English

插座转移

[英]Socket transferring

I have several classes running at the same time which get input from a server. 我有几个同时运行的类,它们从服务器获取输入。 Both have the sockets set up. 两者都有插座。

The problem is that, even though I transfer the same data between the classes, when the data arrives, it is not the same. 问题是,即使我在类之间传输了相同的数据,当数据到达时,它也不相同。

Here is the sending method: 这是发送方法:

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

And here is the receiving-method: 这是接收方法:

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

When I receive the Vector on all my clients, the elements in it are different. 当我在所有客户上收到Vector时,其中的元素是不同的。 It is not the content of the Vector I tried to transfer. 它不是我尝试传输的Vector的内容。

What am I missing? 我想念什么?

The problem is likely with your use of Serialization / ObjectOutputStream. 您使用Serialization / ObjectOutputStream可能会出现问题。 When an object is serialized ObjectOutputStream keeps internal records to "optimize" the serialization process, so that if you serialize the same object twice it simply repeats the ID and assumes the object hasnt changed . 序列化对象时,ObjectOutputStream会保留内部记录以“优化”序列化过程,因此,如果对相同的对象进行两次序列化,它只会重复ID并假定对象尚未更改 For example if you run the code: 例如,如果您运行代码:

ObjectOutputStream oos = new ObjectOutputStream();
MyObject[] arr = new MyObject[]{myObject};
oos.write(myObject);
oos.write(arr);

the output might look like (note not actual format just an example): 输出可能看起来像(注意不是实际格式,只是一个示例):

[[myObject;id=357;foo=bar;baz=36;]]
[[MyObject[];id=358;data={id=357}]]

Note that the array will not serialize the object again, but rather just an id to the already serialized version. 请注意,数组不会再次序列化对象,而只是已序列化版本的ID。 Taking it one step further if you have the code: 如果有代码,请更进一步:

ObjectOutputStream oos = new ObjectOutputStream();
oos.write(myObject);
myObject.setBaz(99999);
oos.write(myObject);

You'll end up with: 您最终将得到:

[[myObject;id=357;foo=bar;baz=36;]]
{id=357}

Note that even though the object changed only the internal id is serialized . 请注意, 即使对象已更改,也只会序列化内部ID The trick is when you are writing objects you need to clear the internal state of the ObjectOutputStream, which can be accomplished with reset(). 诀窍是在编写对象时,您需要清除ObjectOutputStream的内部状态,这可以通过reset()完成。 From the javadocs: 从javadocs:

Reset will disregard the state of any objects already written to the stream. 重置将忽略任何已写入流的对象的状态。 The state is reset to be the same as a new ObjectOutputStream. 将状态重置为与新的ObjectOutputStream相同。

So if you take the previous example and add reset: 因此,如果采用前面的示例并添加reset:

ObjectOutputStream oos = new ObjectOutputStream();
oos.write(myObject);
myObject.setBaz(99999);
oos.reset();
oos.write(myObject);

You should get as output the expected behaviour of: 您应该获得以下行为的预期输出:

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

One things to be careful of is to note that the second serialization will now be considered a different object than the original serialization. 要注意的一件事是要注意,第二个序列化现在将被视为与原始序列化不同的对象 Depending on how you are transferring the data and the internal relationship you must be careful not to reset the stream too early if objects share references with one another and you want those relationships to be maintained. 根据对象的数据传输方式和内部关系,如果对象之间共享引用并且希望维护这些关系,则必须小心不要太早重置流。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM