要用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都是必须是有用的,否则就会出错。