在上章(java socket套接字編程入門)中,服務端只能處理一次,accept()是一種阻塞狀態,因此它只能同時處理一個請求,其它的請求只能排隊等待前面的處理完成。
為了支持多任務同時處理的能力,首先不要讓主服務運行完成即結束,而是一種死循環的方式,讓一直等待接收,其次,處理數據的需要另開線程進行,即socket的生命周期置於新開線程中。
先定義SocketHandler作為線程單獨處理socket。
public class SocketHandler implements Runnable { private Socket socket; SocketHandler(Socket socket) { this.socket = socket; } @Override public void run() { BufferedReader bufferedReader = null; PrintWriter writer = null; try { System.out.println("thread:\t" + Thread.currentThread().getName() ); bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//true,表示自動刷新,不需要人為觸發 writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true); String userInput; while ((userInput = bufferedReader.readLine()) != null) { if ("exit".equals(userInput)) { System.out.println("退出連接通信\t"); break; } System.out.println("接收內容:\t" + userInput); String result = "服務器時間:" + LocalDateTime.now() +"\t" + new StringBuilder(userInput).reverse(); writer.println(result); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (writer != null) writer.close(); if (bufferedReader != null) bufferedReader.close(); socket.close(); } catch (IOException ioException) { ioException.printStackTrace(); } } } }
server服務端:
public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(9090); //固定線程池來接收處理 Executor executor = Executors.newFixedThreadPool(3); //死循環,保證主線程不退出 while (true){ executor.execute(new SocketHandler(serverSocket.accept())); } }
client客戶端:
public class Client { public void send(String message){ Socket socket = null; BufferedReader bufferedReader = null; PrintWriter writer = null; try { socket = new Socket("127.0.0.1",9090); //發送數據到服務端 writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true); writer.println(message); System.out.println("發送內容:\t"+message); //接收服務端返回數據流 bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String input = null; while ((input = bufferedReader.readLine()) != null){ System.out.println("接收服務端數據:\t"+input); //退出指令,關閉連接 writer.println("exit"); break; } } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (writer != null) writer.close(); if (bufferedReader != null) bufferedReader.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { Client client = new Client(); for (int i = 0; i < 10; i++) { String text = RandomStringUtils.randomAlphabetic(5); client.send(text); } }
new PrintWriter("c://text.txt");
BufferedWriter:字符緩沖輸出流(高級流),將文本寫入字符輸出流,緩沖各個字符,從而提供單個字符、數組和字符串的高效寫入。 可以指定緩沖區的大小,或者接受默認的大小。在大多數情況下,默認值就足夠大了。
提供了一個newLine()方法,通知流結束。因此如果把上面的PrintWriter 換成BufferedWriter
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bufferedWriter.write(result); bufferedWriter.newLine(); bufferedWriter.flush();