我正在尝试编写一个接受文件的服务器,并使用DataInputStream和BufferedInputStream将其写入某些目录。
服务器获取'用户名(字符串)' '文件数(int)' '文件名(字符串)' '每个文件的大小(长)'和'未解释字节的文件内容(byte[])'
,如果一切都成功,那么我应该发送布尔值。
但问题是它没有正确接收文件。
有时我收到"管道破裂"错误消息或文件损坏后,我收到。
我看了我的代码4个小时,没有找到问题。
你能帮我一下吗?您可以假设客户端工作正常。
首先,您不必关闭所有这些流。这可能就是你看到管道破裂问题的原因。您只需要关闭输入和输出流。
DataInputStream din = new DataInputStream( new BufferedInputStream( socket.getInputStream() ) );
DataOutputStream dout = new DateOutputStream( new BufferedOutputStream( socket.getOutputStream() );
try {
} finally {
din.close();
dout.close();
}
你不需要关闭所有这些流的原因是因为当din/dout.close()被调用时,你的Buffered* streams和套接字InputStream/OutStream将被关闭。它们将通过它们链接到的引用关闭流。你也可以去掉所有的if(blah != null)垃圾,因为如果你到达finally子句,你就知道它们是非空的。如果你不在try中添加new,就会出现这种情况。
你也泄漏了你的FileOutputStream,因为你用第二个新的FileOutputStream()覆盖了fos变量。您对SUBMIT_DONE文件做了什么?这真的很奇怪。这样做不是个好主意。不要像那样两次使用变量引用。我可能会在循环后关闭第一个文件。考虑用try {} finally {fos.close();} .
你可以试着用一些方法把它分开。放弃静电干扰。
更新:
你认为下面这句话到底在做什么?
while(c!=' ') {
userName += c;
c = din.readChar();
}
根据您从客户端或服务器发送数据的方式,您可以使用:
String userName = din.readUTF();
记住,使用DataInputStream,您正在处理格式化的二进制数据。您还对文件名重复了相同的循环代码。如果不能使用readUTF(),那么创建一个方法来包装该循环并返回一个字符串,然后从这两个地方调用它。您有各种各样的安全问题,允许客户端向您上传原始文件名和文件。我希望你正在构建的服务器没有被部署到生产环境中。
您还需要刷新并关闭通过套接字接收的每个文件,以便将发送的全部数据完全写入文件。