socket.shutdownOutput()的理解

看某神视频的时候,发现不用socket.shutdownOutput()服务端就会被阻塞,阻塞在如下代码块中:

后面想了下,其实在客户端代码中不调用socket.close()也会导致阻塞。

说回到客户端,如果不加如下代码就会阻塞。因为服务器会一直等待客户端的输出。既然服务器阻塞了,客户端等待着服务器的输出,也会被阻塞,所以导致客户端和服务端都被阻塞。

调用Socket.shutdownOutput()方法后,客户端输出的数据都将被发送,并加上 TCP 的正常连接终止序列(-1,也就是服务端终止循环的判断条件),这样服务端读取数据时就不会被阻塞了。

想必socket.close()也做了类似的事情。

但是本代码需要接收服务器的响应,所以不能关闭socket,只能单向关闭客户端输出流。

客户端代码如下:

public static void main(String[] args) {
        try {
            Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
            OutputStream os = socket.getOutputStream();

            FileInputStream fis = new FileInputStream(new File("D:\\2021\\ksnet\\src\\捕获.JPG"));
            byte[] buffer = new byte[1024];
            int len;
            while((len = fis.read(buffer)) != -1) {

                os.write(buffer,0,len);
            }

            //不加则会阻塞
            socket.shutdownOutput();

            //accept server message
            InputStream inputStream = socket.getInputStream();
            byte[] buffer2 = new byte[1024];
            int len2;

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            while((len2 = inputStream.read(buffer2)) != -1) {
                baos.write(buffer2);
            }

            System.out.println(baos.toString());

            baos.close();
            inputStream.close();

            fis.close();
            os.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

服务端代码如下:

public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(9000);

            Socket accept = serverSocket.accept();

            InputStream inputStream = accept.getInputStream();

            byte[] buffer = new byte[1024];
            int len;

            FileOutputStream fos = new FileOutputStream(new File("D:\\2021\\ksnet\\src\\receive.JPG"));
            while((len = inputStream.read(buffer)) != -1) {
                fos.write(buffer,0,len);
            }

    
            //notify client
            OutputStream outputStream = accept.getOutputStream();
            outputStream.write("服务器收到了".getBytes());
            outputStream.close();

            fos.close();
            accept.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }

 


版权声明:本文为u011403239原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。