java中使用ObjectOutputStream和ObjectInputStream时产生的“invalid stream header”错误解决方法

来源:互联网 发布:3dmax2017 mac破解版 编辑:程序博客网 时间:2024/04/29 21:26

 要用java的socket实现图片的传输,即从服务器端将.bmp图片一张一张的发到客户端并显示出来,很自然的想到了使用ObjectOutputStream和ObjectInputStream的对象流。程序写起来挺简单,但是在运行的时候会在某一个不确定的时刻发生“invalid stream header”异常,不知道是什么原因。

上网查了一下,有的说是没有序列化serializable,有的说是ObjectOutputStream必须放在ObjectInputStream前面,反正说什么的都有啦。但我试了一下,还是照样会出现那个异常,搞了我一下午,很是郁闷。后来干脆死马当活马医了,客户端那加了一个已经接受的反馈信号,每接到一张图片就发一个接受成功反馈,服务器只有受到这个反馈后才继续发送图片。呵呵,结果那个异常就不出现了!

不知道是什么原因,请路过的各位有知道的告诉一下小弟。以下是源代码:

server:

package server;

import java.awt.Image;
import java.awt.event.*;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.util.*;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

public class ServerListener implements ActionListener
{
 private ServerGUI g;
 private Socket client;
 public ServerListener(ServerGUI g)
 {
  this.g = g;
 }
 public void actionPerformed(ActionEvent e)
 {
  if(e.getSource()==g.getLoadButton())
  {
   try
   {
    //while(true)
    //{
     //
     
     int i = 1;
     long begintime = 0;
     long endtime = 0;
     while(i<=15)
     {
      if(i==1)
      {
       begintime = new Date().getTime();
      }
      String path = "image//"+i+".bmp";
      Image img = ImageIO.read(new File(path));
      ImageIcon icon = new ImageIcon(img);
      ObjectOutputStream outputobject = new ObjectOutputStream(new BufferedOutputStream(client.getOutputStream()));
      outputobject.writeObject(icon);
      outputobject.flush();
      i++;
      BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
      while(!in.readLine().equals("ok"))
      {
      }
      if(i==15)
      {
       endtime = new Date().getTime();
       System.out.println(endtime-begintime);
      }
     }
     
    //}
   }catch(Exception ex)
   {
    ex.printStackTrace();
   }
   
  }
  if(e.getSource()==g.getConnButton())
  {
   try
   {
    ServerSocket server = new ServerSocket(65000);
    server.setSoTimeout(500000);
    client = server.accept();
    System.out.println("connection has been established!");
    g.getConnButton().setEnabled(false);
   }catch(Exception ex)
   {
    System.out.println("failed because of timeout!");
    ex.printStackTrace();
   }
  }
 }
}

client:

package client;

import java.awt.event.*;
import java.awt.*;
import javax.imageio.*;
import java.io.*;

import javax.swing.*;
import java.util.*;
import java.net.*;

public class ClientListener implements ActionListener
{
 private ClientGUI g;
 private Socket client;
 public ClientListener(ClientGUI g)
 {
  this.g = g;
 }
 public void actionPerformed(ActionEvent e)
 {
  if(e.getSource()==g.getConformButton())
  {
   new Thread(new RunImage()).start();
  }
  if(e.getSource()==g.getConnButton())
  {
   try
   {
    client = new Socket("127.0.0.1",65000);
    g.getConnButton().setEnabled(false);
    new Thread(new GetFromServer()).start();
   }catch(Exception ex)
   {
    ex.printStackTrace();
   }
  }
 }
 public class GetFromServer implements Runnable
 {
  public void run()
  {
   try
   {
    while(true)
    {
     ObjectInputStream inputobject = new ObjectInputStream(new BufferedInputStream(client.getInputStream()));
     ImageIcon icon = (ImageIcon)inputobject.readObject();
     g.getLabel().setIcon(icon);
     PrintWriter out = new PrintWriter(client.getOutputStream());
     out.print("ok/n");
     out.flush();
    }
   }catch(Exception e)
   {
    e.printStackTrace();
   }
  }
 }
 public class RunImage implements Runnable
 {
  public void run()
  {
   try
   {
    JLabel imagelabel = g.getLabel();
    int i = 1;
    Date begin = new Date();
    long begintime = begin.getTime();
    while(i<=15)
    {
     String path = "image//"+i+".bmp";
     Image img = ImageIO.read(new File(path));
     ImageIcon icon = new ImageIcon(img);  
     imagelabel.setIcon(icon);
     imagelabel.setVisible(true);
     i++;
    }
    Date end = new Date();
    long endtime = end.getTime();
    System.out.println(endtime-begintime);
    
   }catch(Exception ex)
   {
    ex.printStackTrace();
   }
  }
 }
}

 

今天终于弄懂一部分了,好像每个socket都要有一个inputstream和outputstream,而且这两个stream都是必须是有用的,否则就会出错。