Bootstrap

关于socket 使用流的flush()目标接收不到数据,close()socket就会关闭的问题

一、先公示代码

1.1、服务端

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Server {
    public static void main(String[] args) {

        try {
            ServerSocket serverSocket = new ServerSocket(5000);
            while (true) {
//                一直等待socket连接
                System.out.println("等待建立连接");
                Socket accept = serverSocket.accept();
                System.out.println("建立连接成功");
                InputStream is = accept.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                String str = "";
                while ((str = br.readLine()) != null) {
                    System.out.println("获取到服务端数据:"+str);
                }
                Scanner scanner = new Scanner(System.in);
                System.out.println("请输入内容:");
                String reply = scanner.nextLine();

                OutputStream os = accept.getOutputStream();
                os.write(reply.getBytes());
                os.flush();
                if (reply.equals("退出")){
                    break;
                }
                os.close();
                br.close();
                is.close();
                accept.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.2 客户端

package nj.zb.kb21.socket.test;


import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class Client {

    public static void main(String[] args) {
        while (true) {
            try {
                Socket socket = new Socket("127.0.0.1", 5000);
                Scanner scanner = new Scanner(System.in);
                System.out.println("请输入内容:");
                OutputStream os = socket.getOutputStream();
                String str = scanner.next();
                os.write(str.getBytes());
                os.flush();
                os.close();
//                socket.shutdownOutput();
                InputStream is = socket.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                String reply = "";
                while ((reply = br.readLine()) != null) {
                    System.out.println(reply);
                }
                if (str.equals("退出")){
                    break;
                }
                br.close();
                is.close();
                os.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

二、说明问题

2.1、理想状态

在以上代码中想想的效果应该是下方图片效果,双方逐个发送信息,来完成对话知道一方输入退出 在这里插入图片描述

2.2、现实情况

出现了以下情况(到达os.close()把所有资源释放。),通过询问,查资料得知是由于流的原因导致。
在这里插入图片描述

2.3、另一种情况

将os.close() 放到最后,出现了下方情况, 使得服务端并没有获取到客户端的数据
在这里插入图片描述

三、说明情况

这里说明其中socket和流里面的三个方法

方法描述
OutputStream中的flush()刷新输出流并强制写入所有缓冲的输出字节
OutputStream中的close()关闭此输出流并释放与此流相关的任何系统资源
Socket中的shutdownOutput()禁用此套接字的输出流

上方客户端的方法应当使用socket中的shutdownOutput()方法
使用flush()方法 并没有关闭socket中的输出流导致程序以为还会写入字节
使用clost()方法 彻底关闭了输出流 并且还把socket也给释放了,导致客户端关停

;