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

标签 java sockets client-server

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

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

服务器逻辑:

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 个字节。这会导致两段代码出现错误:

  • 服务器错误地假设从文件中读取的每个 block 的长度始终恰好是 1024 字节,并将整个缓冲区发送到客户端。
  • 客户端可能无法在单次迭代中读取整个 block 。然后,它将把剩余部分的第一个字节视为 boolean 值,并与服务器不同步。

要解决此问题,您可以:

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

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

关于java - 通过不同计算机上的套接字发送大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53103463/

相关文章:

java - 从 asynctask 获取结果并处理它

java - OnClick 不适用于 LinearLayout

java - SQSEvent 不存在于 aws-lambda-java-events 1.x 中,AmazonS3 不存在于 aws-lambda-java-events 2.x 中?

android - 如何将网络状态从阻塞状态转换为连接状态

java - 如何在 RMI 中正确注册服务器上的客户端?

java - indexOf 总是返回 -1

python - 需要澄清 socket.recv 的行为方式

c - 在 C 中以 block 的形式将内存写入套接字

javascript - 获取跨域客户端请求页面内容

C#/C++ 客户端-服务器应用程序