Java - 通过 ObjectOutputStream read/writeObject() 从服务器向客户端发送 ImageIcons 时出错

Java - Error Sending ImageIcons from server to client via ObjectOutputStream read/writeObject()

背景不多,目前正在尝试完成我的学位作业,正在尝试实现 'Auction House' 本地服务器-客户端程序,客户端可以在该程序中对保存在服务器上的项目进行投标。当新客户端连接到服务器时,用户必须注册 his/her 名称,然后服务器将向客户端发送所有项目信息。

目前所有其他信息都正确发送,但是当我尝试通过 ObjectOutputStream 将项目的图像发送到客户端时,服务器总是无法发送 ImageIcons,然后当我断开客户端连接时,我遇到了这个错误消息:

    Exception in thread "main" java.io.StreamCorruptedException: invalid type code: 53 at java.io.ObjectInputStream.readObject0(Unknown Source)
   at java.io.ObjectInputStream.readObject(Unknown Source)
   at AuctionClient.retrieveItemInformation(AuctionClient.java:365)
   at AuctionClient.main(AuctionClient.java:341)

我认为这可能与我试图通过输出流直接发送 ImageIcons 而不是使用 serialisable 有关,但我们的 java 讲师告诉我们 ImageIcon 不需要它才能正常工作所以我不确定,任何建议都会很棒!我将把 server/clients 的代码放在下面!

服务器线程代码:

public ClientHandler(Socket socket, BiddingItem item1, BiddingItem item2, int number) throws IOException
{
    client = socket;
    outputImage = new ObjectOutputStream(client.getOutputStream());
    input = new Scanner(client.getInputStream());
    output = new PrintWriter(client.getOutputStream(), true);
    startedItem1 = item1;
    startedItem2 = item2;
    clientNumber = number;
    images = new ImageIcon[2];
    images[0] = startedItem1.getImage();
    images[1] = startedItem2.getImage();
}

正在尝试向客户端发送信息:

public void run()
{
    //previous code...
    for (int i=0; i<images.length;++i)
    {
        try 
        {
            outputImage.writeObject(images[i]);
        }
        catch (IOException ioEx)
        {
            System.out.println("\n**ERROR: Unable to send Item " + i + " image to client!**");
        }
        try 
        {
            outputImage.flush();
        } 
        catch (IOException e1) 
        {
            System.out.println("\n**ERROR: Unable to flush OutputObjectStream!**");
        }
    }

创建输入流的客户端:

public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException 
{
    //previous code
    try
    {
        txtBoxServerMessage.setText("CLIENT: Attempting to connect to server...");
        Thread.sleep(2000);
        socket = new Socket(host, PORT);
        inputFromServer = new Scanner(socket.getInputStream());
        inputImageFromServer = new ObjectInputStream(socket.getInputStream());
        outputToServer = new PrintWriter(socket.getOutputStream(), true);
    }
    catch(IOException ioEx)
    {
        txtBoxServerMessage.setText("CLIENT-ERROR: Unable to connect to server! Exiting...");
        Thread.sleep(2000);
        System.exit(1);
    }
}

客户端接受信息的函数:

private static void retrieveItemInformation() throws InterruptedException, ClassNotFoundException, IOException
{
    txtBoxServerMessage.setText("CLIENT: Waiting for Item Information...");
    Thread.sleep(3000);

    clientNumber = Integer.parseInt(inputFromServer.nextLine());

    item1Code = inputFromServer.nextLine();
    item1Desc = inputFromServer.nextLine();
    item1Deadline = inputFromServer.nextLine();
    item1AuctionValue = Double.parseDouble(inputFromServer.nextLine());

    item2Code = inputFromServer.nextLine();
    item2Desc = inputFromServer.nextLine();
    item2Deadline = inputFromServer.nextLine();
    item2AuctionValue = Double.parseDouble(inputFromServer.nextLine());

    item1Image = (ImageIcon)inputImageFromServer.readObject(); // READING IMAGE 1
    item2Image = (ImageIcon)inputImageFromServer.readObject(); // READING IMAGE 2

    txtBoxServerMessage.setText("DEBUG: FINISHED IMAGE");
    txtBoxServerMessage.setText("CLIENT: Information Recieved! Displaying...");
    Thread.sleep(1000);
    comboItemSelect.addItem(item1Code);
    comboItemSelect.addItem(item2Code);
    txtBoxClientNumber.setText(String.valueOf(clientNumber));

    updateDisplay();

}

干杯!

问题是这样的:

outputImage = new ObjectOutputStream(client.getOutputStream());
// ...
output = new PrintWriter(client.getOutputStream(), true);

您不能将单个 OutputStream 包装在两个不同的包装器中。它们各自的状态和缓冲不兼容。

特别是,如果您使用 ObjectOutputStream 以外的任何内容写入一个字节,对象流就会损坏。

如果要同时发送对象和文本,可以将String对象写入ObjectOutputStream。您也可以直接调用ObjectOutputStream.writeUTF。

问题已解决,在客户端和服务器中删除了 Printwriter 和 Scanner 流并将它们替换为 Object 流,并使用了 .writeObject 和 readObject 方法,我还需要确保正确实现图像的路径.感谢您的帮助!