通过不同计算机上的套接字发送大文件
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()
来确保
将读取许多字节。
我已经创建了一个基本的客户端-服务器程序,可以将文件从服务器传输到客户端。由于该文件大约为 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()
来确保 将读取许多字节。