今天学习了java 的网络编程中的 Socket , 就自已写了一个客户端 Socket 和一个服务端 ServerSocket, 测试时发现, 服务端接收到了客户端发送过来的数据, 而客户端没有接收到服务端返回的消息, 下面给出问题代码


客户端代码

Socket socket = new Socket("127.0.0.1", 8888);
        //获取socket中的输出流
        OutputStream os = socket.getOutputStream();
        //在输出流中写入要发送给服务端的数据
        os.write("我是一个努工作,还不粘人的老码农".getBytes());
        //获取socket中的输入流,用来接收服务器返回的数据
        InputStream is = socket.getInputStream();
        int len = 0;
        byte[] b = new byte[1024];
        while((len = is.read(b))!=-1){
            System.out.println(new String(b,0,len));
        }
        socket.close();
    }

服务端代码

//创建一个服务器socket
        ServerSocket serverSocket = new ServerSocket(8888);
        //获取客户端的socket对象
        Socket accept = serverSocket.accept();
        //获取一个输入流对象(服务器端不会去创建输入输出流对象,它使用的是客户端自已的流对象,给客户端发送消息)
        InputStream is = accept.getInputStream();
        int len = 0;
        byte[] b = new byte[1024];
        System.out.println("接收到客户端发来的消息:");
        while((len = is.read(b))!=-1){
            System.out.println(new String(b,0,len));
        }
        //显示出客户端发来的消息后,给客户端返回一个消息
        //获取输入流对象
        OutputStream os = accept.getOutputStream();
        os.write("服务器大王收到了你的消息,让你去寻山,快去吧".getBytes());
        accept.close();
        serverSocket.close();

以上代码,分别开启服务端和客户端,发现服务器端可以正常显示收到的数据,而客户端不行
刚开始以为是客户端出了问题, 因为它的结果与预想不符, 后来才发现根本不是人家客户端的事儿,问题出在 服务端的 while((len = is.read(b))!=-1)上面,也就是说 is.read(b) 一直没有返回 -1的值,所以程序就一直在这里循环,卡在这里, 当然也就不会给客户端发送数据了
那么,现在的问题就是 is.read(b) 为什么 接收完数据还不返回-1呢???
这是因为,read方法要读到流的结束标记才会返回 -1 (也就是说要关闭流的时候会返回-1),而我们的 inputStream是客户端的, 我们不可能在客户端 就把 InputStram给关闭了, 因为这个流对象, 服务端也要使用,所以 我们的客户端 socket还有一个方法 shutdownOutput(), 禁止此套接字的输出流,通俗点说,就是给输出流加了一个结束标记, 可以使 is.read()在读的时候可以返回 -1;
所以,客户端的代码中在 os.write()后面要加上一个,结束标记的语句, socket.shutdownOutput(), 它可以添加一个结束标记, 又不至于把 流给关闭