片段:
public void run() {
try {
// Create data input and output streams
ObjectInputStream inputFromClient = new ObjectInputStream(
socket.getInputStream());
ObjectOutputStream outputToClient = new ObjectOutputStream(
socket.getOutputStream());
while (true) {
cop = inputFromClient.readObject();
String[][] m1=new String[][] {{"1", "1","1"}};
Object xx=new getSerialModel(m1);
outputToClient.reset();
outputToClient.writeObject(xx);
outputToClient.flush();
}
}
来自客户的摘录:
//////////////
/// sockt jop
try {
// Create a socket to connect to the server
socket = new Socket("127.0.0."+Math.round(50+Math.random()*50), 8000);
// Create an output stream to send data to the server
toServer = new ObjectOutputStream(socket.getOutputStream());
toServer.flush();
}
catch (IOException ex) {
msgArea.append('\n' + ex.toString() + '\n');
}
///////////////////
//***
///////////////////
buttonSave.addActionListener(new ActionListener()
{ public void actionPerformed(ActionEvent ev)
{
System.out.println("Saving data is not implemented yet.");
String[][] m1={{"0","0","0"}};
for ( int i = 0 ; i < tableModel.getRowCount() ; i++ ){
{ for ( int j = 0 ; j < tableModel.getColumnCount() ; j++ )
m1[i][j]=(String)tableModel.getValueAt(i, j) ;
}
}
getSerialModel obt =new getSerialModel(m1);
try{
toServer.reset();
toServer.writeObject(obt);
toServer.flush();
}
catch (Exception ex) {
msgArea.append("cant reach the server its may be off" + '\n');
}
}
});
// button send msg
buttonsendtest.addActionListener(new ActionListener()
{ public void actionPerformed(ActionEvent ev)
{
try{
fromServer = new ObjectInputStream(socket.getInputStream());
Object mdata = fromServer.readObject();
tableModel.setDataVector((((getSerialModel)mdata).getmodel()), columnNames);
table.updateUI();
}
catch (Exception ex) {
System.out.print(ex.getStackTrace());
msgArea.append("cant reach the server its may be off "+ ex.toString() + '\n');
}
}
});
当我尝试多次从服务器读取可序列化对象时,我得到了这个异常,第一次接收者成功读取它。
java.io.StreamCorruptedException: invalid stream header: 00007571
我该如何解决?
答案 0 :(得分:7)
如果要为同一个套接字输入流创建多个串联的ObjectInputStream实例,这似乎是一个坏主意。如果服务器正在将多个对象写入同一输出流,则存在与每个唯一对象仅发送一次的序列化相关信息,并且只有客户端上的第一个ObjectInputStream实例才能可靠地读取此信息。每个套接字输入流只使用一个ObjectInputStream实例,每个套接字输出流只使用一个ObjectOutputStream实例可能是最安全的实现。
另外,如果要将多个对象写入服务器端的相同 ObjectOutputStream实例(即多个writeObject()调用),这可能会导致流标题客户端输入流读取相同对象(通常是嵌套引用)时可能会多次引用的问题
当对象输出流包装套接字输出流时会发生此问题,因为在正常序列化期间,对对象的第二次和后续引用不描述对象,而是仅使用引用。客户端的ObjectInputStream由于某些原因而不能正确地重建对象,因为它期望的头信息不同(它不会保留以前的readObject()调用);这似乎只发生在套接字流,而不是文件I / O等。第一次 readObject()调用不会发生此问题,而是第二次和后续调用。
如果要继续使用相同的套接字流来编写多个对象,则需要在服务器代码中使用以下内容:
objectOut.reset()
objectOut.writeObject(foo);
reset()调用重新初始化流,忽略先前沿流发送的任何对象的状态。这可确保每个对象都完整地发送,而不需要通常用于压缩ObjectOutputStream数据并避免重复的句柄类型引用。效率较低,但客户端读取时不应有数据损坏。
答案 1 :(得分:0)
从ObjectInputStream.readObject()的文档中,我引用:
从ObjectInputStream中读取一个对象。的班级 对象,类的签名, 和非瞬态的值 和类的非静态字段 读取所有超类型。 类的默认反序列化可以 使用writeObject和覆盖 readObject方法。引用的对象 通过这个对象被传递阅读 这样一个完整的等效图表 对象由重建 的readObject。
根对象在其所有字段和时都完全恢复 它引用的对象是 完全恢复。此时此刻 对象验证回调是 按顺序执行 注册优先事项回调 由对象注册(在 readObject特殊方法)就像它们一样 单独修复。
对于InputStream和类的问题,会抛出异常 不应该反序列化。所有 例外是致命的 InputStream并将其留在 不确定的国家;它取决于 调用者忽略或恢复流 状态。
Specified by: readObject in interface ObjectInput Returns: the object read from the stream Throws: ClassNotFoundException - Class of a serialized object cannot be found. InvalidClassException - Something is wrong with a class used by serialization. StreamCorruptedException - Control information in the stream is inconsistent. OptionalDataException - Primitive data was found in the stream instead of objects. IOException - Any of the usual Input/Output related exceptions.
我猜你是在尝试将一个对象写入对象流之前读取一个对象,或者是一个未刷新输出流的对象。
答案 2 :(得分:0)
您正在尝试读取“对象”类型的对象。它是如何序列化的?你需要确保你正在将对象读入它所写的同一个类中,还记得那些讨厌的serialVersionUID警告吗?这是对象序列化和重构的关键,因此需要匹配类。此外,您需要在类结构更改时更新UID。
答案 3 :(得分:-1)
也许你试图从流中多次读取相同的对象,而服务器只写了一次对象。
或者您在创建相应的ObjectOutputStream之前尝试使用ObjectInputStream,这会使两者之间的通信无效。 ObjectOutputStream在创建时写入序列化流标头,如果它未在相应的ObjectOutputStream之前创建,则该标头将丢失。