javasocket传输
我有几个类同时运行,它们从服务器获取输入。两个都安装了插座
问题是,即使我在类之间传输相同的数据,但当数据到达时,它并不相同
以下是发送方法:
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;
}
以下是接收方法:
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");
}
}
当我收到所有客户的向量时,其中的元素是不同的。这不是我试图传递的向量的内容
我错过了什么
# 1 楼答案
问题可能与序列化/ObjectOutputStream的使用有关。当一个对象被序列化时,ObjectOutputStream会保留内部记录以“优化”序列化过程,因此如果将同一个对象序列化两次,它只会重复ID,假设该对象没有更改。例如,如果运行代码:
输出可能如下所示(请注意,不是实际格式,只是一个示例):
请注意,数组不会再次序列化该对象,而只是已序列化版本的id。如果你有代码,再进一步:
你最终会得到:
请注意,即使对象只更改了内部id,也会序列化。诀窍在于,在编写对象时,需要清除ObjectOutputStream的内部状态,这可以通过reset()完成。从javadocs:
因此,如果您使用上一个示例并添加重置:
您应该获得以下预期行为的输出:
需要注意的一点是,第二个序列化现在将被视为与原始序列化不同的对象。根据传输数据的方式和内部关系,如果对象彼此共享引用,并且希望维护这些关系,则必须小心不要过早重置流