通过不同计算机上的套接字发送大文件

Sending large files over sockets on separate computers

我已经创建了一个基本的客户端-服务器程序,可以将文件从服务器传输到客户端。由于该文件大约为 500MB,因此服务器通过 DataOutputStream 对象将文件作为字节块传输到客户端。虽然当客户端和服务器都在同一台计算机上 运行 时此逻辑工作正常,但当两个程序在不同计算机上 运行 时它不起作用(两台计算机都在同一网络上,我有为两者都禁用了防火墙)

当 运行 在不同的计算机上时,问题是传输了几个字节

服务器逻辑:

byte byteArr[] = new byte[1024];
while((c=fileInputStream.read(byteArr, 0, 1024) != -1))
{
    dataOutputStream.writeBoolean(true);
    dataOutputStream.flush();
    dataOutputStream.write(byteArr, 0, 1024);
    dataOutputStream.flush();
}
 /*When running on different computers, after a few hundred iterations 
   it just stops looping the following lines are never executed*/
dataOutputStream.writeBoolean(false);
System.out.println("Transfer complete");

客户端逻辑

byte byteArr[] = new byte[1024];
while(dataInputStream.readBoolean())
{
     dataInputStream.read(byteArr, 0, 1024);
     fileOutputStream.write(byteArr, 0, 1024);
}

read(buf, 0, 1024) 调用 保证准确读取 1024 字节。这会导致两段代码出现错误:

  • 服务器错误地假设从文件中读取的每个块总是恰好 1024 字节长,并将整个缓冲区发送给客户端。
  • 客户端可能不会在一次迭代中读取整个块。然后它将余数的第一个字节视为布尔值并与服务器不同步。

要解决此问题,您可以:

  • 在发送文件之前发送文件大小(如果已知), 然后继续阅读,直到你读完那么多字节。

  • 或发送 c(块大小)而不是单个布尔值, 然后使用 dataInputStream.readFully() 来确保 将读取许多字节。