【发布时间】:2018-07-22 01:51:31
【问题描述】:
我正在尝试构建一个客户端-服务器程序,其中服务器将图像发送到客户端,客户端在 JFrame 中显示接收到的图像。我正在将服务器端的 Image 转换为 ImageIcon 对象并通过 ObjecOutputStream 将其发送到客户端。但它失败并在服务器端给我无法加载图像内容错误,它发生在调用 ObjectOutputStream.writeObject() 方法时。
服务器端代码
import java.io.*;
import java.net.*;
import javax.swing.*;
public class ImageServer{
private static ServerSocket serverSocket;
private static final int PORT = 1234;
public static void main(String[] args){
System.out.println("Opening port…\n");
try{
serverSocket = new ServerSocket(PORT);
}
catch(IOException ioEx){
System.out.println("Unable to attach to port!");
System.exit(1);
}
while(true){
try{
Socket connection = serverSocket.accept();
ObjectOutputStream outStream =new ObjectOutputStream(
connection.getOutputStream());
ImageIcon icon=new ImageIcon("//Give image path//");
System.out.println(icon.getImageLoadStatus());// To check if image is loded correctly or not.
outStream.writeObject(icon);
outStream.flush();
}
catch(IOException ioEx){
ioEx.printStackTrace();
}
}
}
}
只需提供图像文件的路径,用于测试目的。
客户端代码
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ImageClient extends JFrame{
private InetAddress host;
private final int PORT = 1234;
private ImageIcon image;
public static void main(String[] args){
ImageClient pictureFrame = new ImageClient();
pictureFrame.setSize(340,315);
pictureFrame.setVisible(true);
pictureFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public ImageClient(){
try{
host = InetAddress.getLocalHost();
}
catch(UnknownHostException uhEx){
System.out.println("Host ID not found!");
System.exit(1);
}
try{
Socket connection = new Socket(host,PORT);
ObjectInputStream inStream =new ObjectInputStream(
connection.getInputStream());
image = (ImageIcon)inStream.readObject();
connection.close();
}
catch(IOException ioEx){
ioEx.printStackTrace();
}
catch(ClassNotFoundException cnfEx){
cnfEx.printStackTrace();
}
repaint();
}
public void paint(Graphics g){
image.paintIcon(this,g,0,0);
}
}
服务器端产生错误
java.io.IOException: failed to load image contents
at javax.swing.ImageIcon.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at ImageServer.main(ImageServer.java:27)
这是以下书籍的代码摘录: http://www.springer.com/us/book/9781447152538
【问题讨论】:
-
我假设你实际上并没有使用 "//Give image path//"。如果是这样,那可能是您的问题。
-
您已经测试过,在尝试发送图像之前,您实际上已经成功读取了图像,对吗? ——看起来不像你。我自己,我会通过
ImageIO.read(...)获取图像,并首先测试它是否存在并且不为空。此外,通常最好将图像作为资源而不是文件。 -
icon.getImageLoadStatus必须返回值MediaTracker.COMPLETE,但由于它是加载图像的异步方法,因此不能保证返回完整的图像。相反,使用ImageIO.read会失败并返回IOException或返回完全实现的图像。请注意,返回URL更合适,客户端可以通过该URL自行下载图像或使用base64 编码之类的东西。对象序列化只会导致更多问题 -
@ck0049 ...请不要只是不这样做。我已经以这种方式使用
ImageIcon超过 17 年,我保证它以这种方式工作ImageIcon(Image)期望java.awt.Image。如果您看一下JavaDocs forBufferedImage,您会发现它从...延伸...java.awt.Image???? -
@ck0049 那么问题是,图像不存在于您认为存在的位置,或者它不是有效的图像格式。由于
ImageIO支持比ImageIcon更广泛的图像格式,这可能会开始向您暗示部分问题的根源。您实际上想读取哪种类型的图像?
标签: java swing sockets imageicon objectoutputstream