发送套接字后,Jar文件已损坏

时间:2013-11-16 23:08:27

标签: java sockets jar inputstream outputstream

所以我正在构建一个需要内置自动更新功能的程序,因为我已经完成并测试了它,似乎当我将jar文件发送到套接字并将其写入新制作的jar时文件缺少5KB(每次......即使尺寸发生变化)尺寸也会因此而变得腐败。

这是我的代码:

package server.update;

import java.io.*;
import java.net.Socket;

public class UpdateThread extends Thread
{
BufferedInputStream input; //not used
BufferedInputStream fileInput;
BufferedOutputStream output;

public UpdateThread(Socket client) throws IOException
{
    super("UpdateThread");
    output = new BufferedOutputStream(client.getOutputStream());
    input = new BufferedInputStream(client.getInputStream());
}

public void run()
{
    try
    {
        File perm = new File(System.getProperty("user.dir")+"/GameClient.jar");
        //fileInput = new BufferedInputStream(new FileInputStream(perm));
        fileInput = new BufferedInputStream(new FileInputStream(perm));

        byte[] buffer = new byte[1024];
        int numRead;
        while((numRead = fileInput.read(buffer)) != -1)
            output.write(buffer, 0, numRead);

        fileInput.close();
        input.close();
        output.close();
        this.interrupt();
    }
    catch(Exception e)
    {e.printStackTrace();}
}
}

这是等待来自客户端的连接的类,然后在连接时立即将更新推送到它们。 File Perm是我想发送的jar文件,无论出于什么原因,它似乎错过了最后5个字节,或者客户端没有读取最后5个字节(我不知道哪个)。以下是客户在此处接收信息的类别:

public void getUpdate(String ip) throws UnknownHostException, IOException
{
    System.out.println("Connecting to update socket");
    update = new Socket(ip,10004);
    BufferedInputStream is = new BufferedInputStream(update.getInputStream());
    BufferedOutputStream os = new BufferedOutputStream(update.getOutputStream());

    System.out.println("Cleaning GameClient.jar file");
    File updated = new File(System.getProperty("user.dir")+"/GameClient.jar");
    if(updated.exists())
        updated.delete();
    updated.createNewFile();

    BufferedOutputStream osf = new BufferedOutputStream(new FileOutputStream(updated));

    System.out.println("Writing to GameClient.jar");
    byte[] buffer = new byte[1024];
    int numRead = 0;
    while((numRead = is.read(buffer)) != -1)
        osf.write(buffer, 0, numRead);

    System.out.println("Finished updating...");
    is.close();
    os.close();
    update.close();
    osf.close();
}

感谢任何帮助。谢谢!

3 个答案:

答案 0 :(得分:2)

你关闭太多了。删除update.close()is.close().这两个都关闭套接字,这可以防止缓冲流'osf'在关闭时自动刷新。关闭输入流或输出流或套接字将关闭另一个流和套接字。因此,您应该只关闭缠绕在套接字上的最外面的输出流,在本例中为osf,,并且可能是最后一个块中的套接字本身。

答案 1 :(得分:0)

感谢MDR的回答,它有效!!

我必须在UpdateThread类中更改以下代码行:

在:

fileInput.close();
input.close();
output.close();
this.interrupt();

后:

fileInput.close();
output.flush();
output.close();
input.close();
this.interrupt();

你必须在关闭前刷新流,我也切换了订单,因为如果关闭连接到套接字的输入流,它将关闭套接字,然后不会继续关闭输出流或刷新它。

再次感谢!

答案 2 :(得分:-2)

您是否考虑过使用http library将所有连接处理和读/写委托给已知的工作代码?你在这里重新发明了很多轮子。此外,在某些时候,您将要确保您收到的内容是真实且完好无损的(您通过加载课程来实现这一点,这有点危险,尤其是当您以明文形式交换数据时!) ,使用库及其方法将允许您选择HTTPS,允许TLS完成大部分工作。

我还建议您的服务器提前告诉客户端一些元数据 - 无论是内容长度还是散列或校验和,以便客户端可以检测传输中的失败。

This question似乎也有与您的情况相关的答案。祝你好运!