【发布时间】:2021-04-02 09:42:02
【问题描述】:
我目前正在制作一个文件传输服务器,它通过 DatagramPacket 从文件中获取 1024 字节的块(这是分配的要求),然后将文件组装成字节数组,然后通过 HTTP 发送。该系统适用于任何文本文件格式,甚至是非常大的 .c/.txt/.sql 文件,所以我知道我得到了正确的字节。但是,当我尝试使用其他任何东西时,例如 .zip 或 .png,当我在另一侧打开它时,它就会损坏。这也发生在非常小的图像/拉链中。任何想法为什么会发生这种情况?
创建块的类中的代码:
File f = new File(campos[2]);
FileInputStream inputStream = new FileInputStream(f);
inputStream.skipNBytes(chunk);
if (f.length() > chunk + 1024)
quantos = 1024;
else quantos = (int) f.length() - chunk;
byte[] dados = new byte[quantos];
inputStream.read(dados, 0, quantos);
inputStream.close();
pacote = new DatagramPacket(dados, quantos, address, porta);
socket.send(pacote);
来自服务器的代码,将所有块放入一个字节数组中:
while (tamanho > 0) {
serv = procuraServidor();
buf = ("Chunk " + chunk + " " + parametros[1].substring(1) + " ").getBytes();
pacote = new DatagramPacket(buf, buf.length, serv.getKey(), serv.getValue());
dataSocket = new DatagramSocket();
//pede os dados desse chunk
dataSocket.send(pacote);
buf = new byte[1500];
pacote = new DatagramPacket(buf, buf.length);
dataSocket.receive(pacote);
try {
lock.lock();
servidores.add(serv);
} finally {
lock.unlock();
}
if (tamanho > chunkSize)
System.arraycopy(buf, 0, ficheiro, chunk*chunkSize, chunkSize);
else System.arraycopy(buf, 0, ficheiro, chunk*chunkSize, tamanho);
// iniciar thread para tomar conta do pedido
tamanho-= chunkSize;
chunkSet.add(chunk);
chunk++;
}
out.write("HTTP/1.1 200 OK\r\n".getBytes());
out.write(("content type: " + Files.probeContentType(new File (parametros[1].substring(1)).toPath())).getBytes());
out.write(ficheiro);
out.flush();
}
我真的不知道为什么会这样,特别是在非文本文件中。
【问题讨论】:
-
尝试将您的代码隔离到一个独立的客户端和服务器程序中。您应该拿走所有不属于您的问题的部分(例如,我看到您正在使用锁)。最后,请在代码中使用英文名称。
-
谢谢!我隔离了它,问题仍然存在。这是代码:
File file = new File("code5.zip"); byte[] test = new byte[(int)file.length()]; FileInputStream inp = new FileInputStream(file); inp.read(test, 0, (int)file.length()); out.write("HTTP/1.1 200 OK\r\n".getBytes()); out.write(("content type: " + Files.probeContentType(new File ("code5.zip").toPath())).getBytes()); out.write(test); out.flush(); -
我只使用 FileOutputStream 进行测试,而不是通过 HTTP 发送,并且创建的文件完美无缺。所以问题必须是HTTP传输......
-
据我所知,您不会在 content-type 之后发送 CRLF,也不会在 content-length 之后发送 CRLF,更不用说 CRLF 将内容与标头字段分开。
标签: java arrays http corruption file-access