在Java套接字中关闭Streams的正确方法

时间:2013-07-11 04:12:27

标签: java android sockets inputstream

我看到一些关于此的帖子,但我仍然找不到答案。

这是我的服务器与客户端交互的方式:

public void run () {
    try {
        //Read client request
        InputStream is = server.getInputStream();
        byte[] buff = new byte[1024];
        int i;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((i = is.read(buff, 0, buff.length)) != -1) {
            bos.write(buff, 0, i);
            System.out.println(i + " bytes readed ("+bos.size()+")");
        }
        is.close();
        is = null;
        //Do something with client request

        //write response
        OutputStream os = server.getOutputStream();
        os.write("server response".getBytes());
        os.flush();
        os.close();
        os = null;

    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
}

这是客户方:

public void run() {
        try {
            InetAddress serverAddr = null;
            serverAddr = InetAddress.getByName("10.0.2.2");
            socket = new Socket(serverAddr, 5000);

            //Send Request to the server
            OutputStream os = socket.getOutputStream();
            os.write(jsonRequest.toString().getBytes("UTF-8"));
            os.flush();
            os.close();
            os = null;

            //Read Server Response
            InputStream is = socket.getInputStream();
            byte[] buff = new byte[1024];
            int i;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            while ((i = is.read(buff, 0, buff.length)) != -1) {
                bos.write(buff, 0, i);
                System.out.println(i + " bytes readed ("+bos.size()+")");
            }
            is.close();
            is = null;

            //Do something with server response

        } catch (UnknownHostException uhe) {
            sendCallbackError(uhe);
        } catch (IOException ioe) {
            sendCallbackError(ioe);
        }
    }

如您所见,客户端连接并发送请求。服务器读取该请求然后写入客户端将读取的响应。

此代码的问题是客户端中的OutputStream.close()和服务器中的InputStream.close()。正如Javadocs中所述,关闭流将关闭Socket。结果是,当客户端尝试读取服务器响应时,Socket已经关闭。

我设法通过调用Socket.shutdownInputSocket.shutdownOutput来解决此问题。但是我仍在考虑这是否是正确的做法

作为一个注释,当服务器写入响应或客户端读取它时,用close()关闭流不会产生问题(我猜想在客户端和服务器之间同步关闭)。

所以我的问题是:

  1. 正确使用Socket关机方法吗?
  2. 我可以继续使用close()关闭最后一个流(发送和阅读时) 来自服务器的响应)
  3. 可能会发生关闭关闭会保留一些数据 缓冲区,不会被发送?

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

try{
}catch(){
}finally{
if(is!=null){
is.close();
}
if(os!=null){
os.close();
}
}

答案 1 :(得分:0)

  

此代码的问题是客户端中的OutputStream.close()和服务器中的InputStream.close()。正如Javadocs中所述,关闭流将关闭Socket。

正确,但服务器中的InputStream未直接连接到Socket:,它与您不了解的内容相关联。你可以不受惩罚地关闭它,尽管你根本不需要关闭它。如果您愿意,可以关闭服务器中的OutputStream:尽管如此,因为它没有直接连接到Socket,,除了刷新之外,它可能有也可能没有任何影响。

要解决您的实际问题,您不需要关闭客户端中的输出流,但您需要发送适当的Content-Length:标头。这样服务器就知道从客户端读取多少内容。如果这只是GET请求,则内容长度可能为零。你不需要打电话给shutdownOutput(),,虽然我觉得没有什么可以阻止你,并且调用shutdownInput()对网络没有任何作用,所以再次没有任何意义。