所以我正在构建一个需要内置自动更新功能的程序,因为我已经完成并对其进行了测试,似乎当我通过套接字发送 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();
}
任何帮助,不胜感激。谢谢!
你的收盘价太多了。删除update.close()
并is.close().
它们都会关闭套接字,从而防止缓冲流"osf"在关闭时自动刷新。关闭输入流或输出流或套接字将关闭另一个流和套接字。因此,您应该只关闭围绕套接字的最外层输出流,在这种情况下,osf,
,也许套接字本身在 finally 块中以确保。
感谢 MDR 的回答,它奏效了!!
我不得不更改 UpdateThread 类中的以下代码行:
以前:
fileInput.close();
input.close();
output.close();
this.interrupt();
后:
fileInput.close();
output.flush();
output.close();
input.close();
this.interrupt();
您必须在关闭之前刷新流,我也切换了顺序,因为如果您关闭连接到套接字的输入流,它将关闭套接字,然后不会继续关闭输出流或刷新它。
再次感谢!
您是否考虑过使用 http 库将所有连接处理和读取/写入委托给已知的工作代码?你在这里重新发明了很多轮子。此外,在某些时候,您将希望确保您接收的内容是真实且未损坏的(您是通过加载类来做到这一点的,这有点危险,尤其是当您以明文形式交换数据时!同样,使用库及其方法将允许您选择HTTPS,从而允许TLS完成大部分工作。
我还建议您的服务器提前告诉客户端一些元数据,无论如何 - 也许是内容长度,也可能是哈希或校验和,以便客户端可以检测传输中的失败。
这个问题似乎也有与您的情况相关的答案。祝你好运!