后续Input&OutputStream的Java模式

时间:2018-09-15 15:34:28

标签: java sockets io inputstream outputstream

您好,堆栈溢出世界,我一直在Java IO中最直接最常见的问题上苦苦挣扎,现在需要您的帮助来解决它。

在thread.run()中的try块中查看我的这段代码:

                // connect to client socket, and setup own server socket
                clientSocket = new Socket(serverHostname, CLIENT_PORT);

                //send a test command to download a file
                String downloadFileName = "sample.txt";
                DataOutputStream dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
                System.out.println("Sending a request to download file : " + downloadFileName + " from user: Arsa node"); //todo: replace with node user later
                dataOutputStream.writeUTF("D/sample.txt");

                //close socket if host isn't detected anymore, and if socket doesn't become null suddenly
                dataOutputStream.flush();
                dataOutputStream.close();
                System.out.println("****File has been sent****");

                in = new DataInputStream(clientSocket.getInputStream());
                byte[] retrievedFileData = new byte[8036];


                if (in.readInt() > 0) {
                    System.out.println("Starting file download!");
                    in.read(retrievedFileData);
                    System.out.println("File data has been read, converting to file now");

                //closing input stream will close socket also
                    in.close();
                }

                clientSocket.close();

2个使我迷惑不解的主要问题:

  • 为什么需要运行dataOutputStream.close()才能将writeUTF实际将我的字符串发送到服务器套接字,所以我发现当我没有dos.close()时,就不会检索数据另一方面,由于我关闭了它,所以我再也无法从套接字读取信息-似乎在先前关闭输出流时套接字连接已关闭...

    • 遵循某种模式来执行此操作是一种更好的方法吗?对于上下文,我要做的就是将要下载的文件名写入客户端,然后立即读取响应,我希望它是文件的字节,任何错误处理我都将考虑作为一部分我的发展。

总的来说,向套接字写一些东西,然后读取并吸收它的响应应该并不复杂……这里似乎不是这种情况, 任何帮助将不胜感激!如果需要ServerSocket代码片段,我很乐意分享。

1 个答案:

答案 0 :(得分:0)

观察到的行为只是close()的副作用,因为它在关闭以确保发送任何缓冲的数据之前调用flush()。要解决您的问题,您需要调用flush()方法而不是关闭。

此行为并非DataOutputStream所独有:其他许多OutputStream(或Writer)实现均应用缓冲,因此当您要确保数据为发送给客户端,写入磁盘或进行其他处理。

BTW:DataOutputStreamDataInputStream用于特定于Java的非常特定类型的数据序列化协议。您可能需要仔细考虑是否使用了正确的协议。