在使用BufferedReader的readLine方法时,客户端可以发送,但服务端一直接收不到。
示例代码如下:
服务端代码
protected void initialize() throws IOException { int portNumber=9999; //构建socket ServerSocket serverSocket=new ServerSocket(portNumber); while (true){ //开启socket监听端口哦 final Socket socket=serverSocket.accept(); new Thread(new Runnable() { public void run() { //获取输入流 InputStream inputStream= null; BufferedReader bufferedReader=null; try { inputStream = socket.getInputStream(); bufferedReader=new BufferedReader(new InputStreamReader(inputStream)); String data=null; while (true){ if ((data=bufferedReader.readLine())==null){ break; } System.out.println(data); } } catch (IOException e) { e.printStackTrace(); }finally { try { if (socket!=null){ socket.close(); } if (bufferedReader!=null){ bufferedReader.close(); } } catch (IOException e) { e.printStackTrace(); } } System.out.println("server buffered closed"); } }).start(); } }
客户端代码
protected void initialize() throws IOException { int portNumber=9999; Socket socket=null; BufferedWriter bufferedWriter=null; try { socket=new Socket("localhost",portNumber); OutputStream outputStream=socket.getOutputStream(); bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream)); System.out.println("输入点什么给服务器>>"); Scanner scanner=new Scanner(System.in); String msg; while (true){ if ((msg=scanner.nextLine())==null){ break; } System.out.println(msg); bufferedWriter.write(msg); bufferedWriter.flush(); } }catch (IOException e) { e.printStackTrace(); }finally { if (socket!=null){ socket.close(); } } }
debug后发现代码阻塞在data=bufferedReader.readLine()这句
查看源码看到这样一句话
* Reads a line of text. A line is considered to be terminated by any one 读取一行文本,所谓‘一行’是以/n/r结束的,或回车后紧跟换行符的一行文本 * of a line feed ('\n'), a carriage return ('\r'), or a carriage return * followed immediately by a linefeed. * * @param ignoreLF If true, the next '\n' will be skipped * * @return A String containing the contents of the line, not including * any line-termination characters, or null if the end of the * stream has been reached
难道是后面一定要加换行符吗?
解决方法:
我们知道BufferedReader是一个缓冲字符流,不指定buffer的大小时,readLine()使用的buffer有8192个字符。
在达到buffer大小之前,只有遇到"/r"、"/n"、"/r/n"才会返回,否则这段代码将会一直阻塞。
但是这个方法还有另一个特性,如果BufferedReader调用了close方法,则会立刻将读到的返回。
修改客户端的代码
protected void initialize() throws IOException { int portNumber=9999; Socket socket=null; BufferedWriter bufferedWriter=null; try { socket=new Socket("localhost",portNumber); OutputStream outputStream=socket.getOutputStream(); bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream)); System.out.println("输入点什么给服务器>>"); Scanner scanner=new Scanner(System.in); String msg; while (true){ if ((msg=scanner.nextLine())==null){ break; } System.out.println(msg); bufferedWriter.write(msg); bufferedWriter.flush(); bufferedWriter.close(); } }catch (IOException e) { e.printStackTrace(); }finally { if (socket!=null){ socket.close(); } if (bufferedWriter!=null){ bufferedWriter.close(); } } }
运行成功