IO创建Socket通信中慎用BufferReader中的readLine()
在编写Socket的Demo的时候,在Server中使用BufferReader获取从客服端发送过来的内容
package cn.lonecloud.socket; import cn.lonecloud.thread.factory.TraceThreadPool; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.time.Instant; import java.time.LocalDateTime; import java.util.concurrent.ExecutorService; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * @author lonecloud * @version v1.0 * @date 下午5:11 2018/5/9 */ public class SocketServer { //创建线程 static ExecutorService service = new ThreadPoolExecutor(0, 10, 60L, TimeUnit.SECONDS, new SynchronousQueue<>()); //处理消息类 static class HandlerMsg implements Runnable { //客户端socket Socket clientSocket; public HandlerMsg(Socket clientSocket) { this.clientSocket = clientSocket; } @Override public void run() { BufferedReader reader = null; PrintWriter pr = null; try { //获取消息 reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); pr = new PrintWriter(clientSocket.getOutputStream(), true); Instant now = Instant.now(); String s = null; while ((s = reader.readLine()) != null) { pr.append(s); } pr.close(); reader.close(); clientSocket.close(); System.out.println("spend "+(Instant.now().getNano()-now.getNano())); } catch (IOException e) { e.printStackTrace(); } } } }
client
package cn.lonecloud.socket; import java.io.*; import java.net.InetSocketAddress; import java.net.Socket; import java.util.Scanner; /** * @author lonecloud * @version v1.0 * @date 下午5:24 2018/5/9 */ public class SocketClient { public static void main(String[] args) throws IOException { Socket socket=new Socket();
//链接 socket.connect(new InetSocketAddress("localhost",8000)); PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true); //获取输入
Scanner scanner=new Scanner(System.in); String s = scanner.nextLine(); //必须使用println不然会一直卡在这里
printWriter.println(s); printWriter.flush();
//读取数据 InputStream inputStream = socket.getInputStream(); BufferedReader reader=new BufferedReader(new InputStreamReader(inputStream)); //打印
System.out.println("from server"+reader.readLine()); System.out.flush(); printWriter.close(); reader.close(); socket.close(); } }
Main
package cn.lonecloud.socket; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * @author lonecloud * @version v1.0 * @date 下午5:21 2018/5/9 */ public class ServerMain { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; Socket clientSocket = null; serverSocket = new ServerSocket(8000); while (true) { clientSocket = serverSocket.accept(); System.out.println(clientSocket.getRemoteSocketAddress() + "connect"); SocketServer.service.execute(new SocketServer.HandlerMsg(clientSocket)); } } }
出现如下问题,如果Socket中如果对采用如下代码
while ((s = reader.readLine()) != null) { pr.append(s); }
如果其在客户端不采用println打印换行符,将导致客户端与服务器端一直处于工作状态,因为其一直都未接收到"\n"