Java 通过不同计算机上的套接字发送大文件
我创建了一个基本的客户机-服务器程序,将文件从服务器传输到客户机。由于文件大约为500MB,服务器通过DataOutputStream对象将文件作为字节块传输到客户端。当客户端和服务器都在同一台计算机上运行时,此逻辑正常工作,但当两个程序在不同的计算机上运行时,此逻辑不工作(两台计算机都在同一网络上,我已禁用了这两台计算机的防火墙) 在不同的计算机上运行时,问题是会传输几个字节 服务器逻辑:Java 通过不同计算机上的套接字发送大文件,java,sockets,client-server,Java,Sockets,Client Server,我创建了一个基本的客户机-服务器程序,将文件从服务器传输到客户机。由于文件大约为500MB,服务器通过DataOutputStream对象将文件作为字节块传输到客户端。当客户端和服务器都在同一台计算机上运行时,此逻辑正常工作,但当两个程序在不同的计算机上运行时,此逻辑不工作(两台计算机都在同一网络上,我已禁用了这两台计算机的防火墙) 在不同的计算机上运行时,问题是会传输几个字节 服务器逻辑: byte byteArr[] = new byte[1024]; while((c=fileInputS
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()
read(buf,0,1024)
调用不能保证精确读取1024字节。这会导致两段代码中出现错误:
- 服务器错误地认为从文件中读取的每个块总是正好
字节长,并将整个缓冲区发送给客户端1024
- 客户端可能不会在一次迭代中读取整个区块。然后,它会将余数的第一个字节视为布尔值,并与服务器不同步
- 在发送文件之前发送文件大小(如果已知), 然后继续读,直到你读了那么多字节
- 或者发送
(块大小),而不是单个布尔值, 然后使用c
确保 将读取许多字节dataInputStream.readFully()
read
不能保证读取全部数据,但它可能会这样做-在本地设置中可能会这样。好的..因此readFully调用应该是readFully(buff,0,(c-1))是吗?我想应该准备好了(buff,0,c)。最后一个参数是要读取的字节数(不是最后一个字节的索引)。是的…它工作了…刚刚传输了一个379mb的文件…非常感谢您的帮助!!好的,我将尝试第二种方法,因为文件大小可能太大…尽管当两个程序都在同一台电脑上运行时,它是如何顺利工作的?虽然read
不能保证读取全部数据,但它可能会这样做-并且在本地设置中它可能会这样做。好的..因此readFully调用应该是readFully(buff,0,(c-1))是吗?我想应该准备好了(buff,0,c)。最后一个参数是要读取的字节数(不是最后一个字节的索引)。是的…它工作了…刚刚传输了一个379mb的文件…非常感谢您的帮助!!你只需要冲洗一次就可以了。您不需要布尔标志,但需要始终确保只写入两端读取的数据(并且只在客户端读取服务器写入的数据),完成后只需刷新。您不需要布尔标志,但需要始终确保只写入两端读取的数据(并且只在客户端读取服务器写入的数据)