1.socket 伺服器搭建 實例化socket伺服器,迴圈獲取請求 SocketThread類實現多線程通信 單例Chatmanage,對所有客戶端線程管控處理 至此,伺服器搭建完成 2.客戶端(創建兩個客戶端) 客戶端1(監聽指定伺服器,通過控制台輸入消息進行伺服器與客戶端以及客戶端之間的通信, ...
1.socket 伺服器搭建
實例化socket伺服器,迴圈獲取請求
package com.orange.util; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * socket伺服器 * * @author Chengjq * */ public class SocketServer { public static int count = 0; public static void main(String[] args) { // TODO 自動生成的方法存根 int port = 4404; // 首先直接創建serversocket ServerSocket serverSocket = null; Socket socket = null; try { serverSocket = new ServerSocket(port); System.out.println("啟動socketServer成功,等待客戶端的連接"); while (true) { socket = serverSocket.accept(); System.out.println("有新的客戶端請求連接"); SocketThread st = new SocketThread(socket); st.start(); ChatManager.getChatManager().add(st); //啟動定時任務,如果10s內沒有進程 /*Runnable runnable = new Runnable() { int clientNum = 0; public void run() { // task to run goes here clientNum = ChatManager.getChatManager().vector.size(); System.out.println("剩餘客戶端數量:"+clientNum); if(clientNum ==0 ){ System.out.println("連接超時,或者無客戶端連接,關閉serverSocket"); //關閉socket //..... } } }; ScheduledExecutorService service = Executors .newSingleThreadScheduledExecutor(); // 第二個參數為首次執行的延時時間,第三個參數為定時執行的間隔時間 service.scheduleAtFixedRate(runnable, 2, 10, TimeUnit.SECONDS); */ } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { System.out.println("serverSocket已超時"); try { socket.close(); serverSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
SocketThread類實現多線程通信
package com.orange.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * SocketThread實現多線程通信 * * @author Administrator * */ public class SocketThread extends Thread { ServerSocket serverSocket = null; Socket socket = null; public SocketThread(ServerSocket serverSocket,Socket socket) { super(); this.serverSocket = serverSocket; this.socket = socket; } public SocketThread(Socket socket) { super(); this.socket = socket; } public void out(String out) { try { socket.getOutputStream().write(out.getBytes("utf-8")); } catch (IOException e) { e.printStackTrace(); } } public void publish(String out){ ChatManager.getChatManager().publish(this, out); } @Override public void run() { // TODO Auto-generated method stub BufferedReader socketIn = null; PrintWriter socketOut = null; String inMess = null; try { socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); socketOut = new PrintWriter(socket.getOutputStream()); while (true) { inMess = socketIn.readLine(); publish(inMess); if("bye".equals(inMess)){ ChatManager.getChatManager().remove(this); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { System.out.println("已結束當前會話"); socketOut.close(); socketIn.close(); socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
單例Chatmanage,對所有客戶端線程管控處理
package com.orange.util; import java.util.Vector; public class ChatManager { // 實現單例化 private ChatManager() { }; private static final ChatManager cm = new ChatManager(); public static ChatManager getChatManager() {// 返回值為ChatManager return cm; } // 單例化完成 Vector<SocketThread> vector = new Vector<SocketThread>(); public void add(SocketThread st) {// 為當前集合添加SocketThread對象 vector.add(st); } public void remove(SocketThread st) {// 當前客戶端關閉連接 vector.remove(st); } public void removeall() {// 關閉所有連接 for (int i = 0; i < vector.size(); i++) {// 遍歷所有的線程 SocketThread csChatSocket = vector.get(i); if(csChatSocket!=null){ vector.remove(csChatSocket); } } } // 某一個線程向其他的客戶端發送信息 public void publish(SocketThread st, String out) { for (int i = 0; i < vector.size(); i++) {// 遍歷所有的線程 SocketThread csChatSocket = vector.get(i); if (csChatSocket != st)// 判斷不是當前線程就發送此消息 csChatSocket.out(out + "\n"); } } // 向當前線程發信息 public void publish_present(SocketThread st, String out) { st.out(out + "\n"); } }
至此,伺服器搭建完成
2.客戶端(創建兩個客戶端)
客戶端1(監聽指定伺服器,通過控制台輸入消息進行伺服器與客戶端以及客戶端之間的通信,)
package com.orange; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; /** * 客戶端1 * @author Chengjq * */ public class SocketClient1 { @SuppressWarnings("static-access") public static void main(String[] args) { try { //初始化客戶端 Socket socket = new Socket("127.0.0.1", 4404); BufferedReader readline = new BufferedReader(new InputStreamReader(System.in)); //獲取輸出列印流 PrintWriter socketOut = new PrintWriter(socket.getOutputStream()); String outTemp = null; System.out.println("開始準備向伺服器端發起請求---\n自己:"); // 已啟動連接socket伺服器,準備實時接收來自其他客戶端的消息 GetMess getMess = new GetMess(socket); getMess.start(); // 通過控制台發送消息給其他客戶端,以“bye”為結束語 while ((outTemp = readline.readLine()) != null) { //發送信息 socketOut.println(outTemp); socketOut.flush(); if("bye".equals(outTemp)){ break; } } getMess.currentThread().interrupt(); //依次關閉各種流 readline.close(); socketOut.close(); socket.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
客戶端2
package com.orange; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class SocketClient2 { @SuppressWarnings("static-access") public static void main(String[] args) { try { //初始化客戶端 Socket socket = new Socket("127.0.0.1", 4404); BufferedReader readline = new BufferedReader(new InputStreamReader(System.in)); //獲取輸出列印流 PrintWriter socketOut = new PrintWriter(socket.getOutputStream()); String outTemp = null; System.out.println("開始準備向伺服器端發起請求---\n自己:"); // 已啟動連接socket伺服器,準備實時接收來自其他客戶端的消息 GetMess getMess = new GetMess(socket); getMess.start(); // 通過控制台發送消息給其他客戶端,以“bye”為結束語 while ((outTemp = readline.readLine()) != null) { //發送信息 socketOut.println(outTemp); socketOut.flush(); if("bye".equals(outTemp)){ break; } } getMess.currentThread().interrupt(); //依次關閉各種流 readline.close(); socketOut.close(); socket.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
GetMess(多線程處理獲取其他客戶端的消息並且展示)
package com.orange; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Socket; public class GetMess extends Thread { Socket socket = null; public GetMess(Socket socket) { super(); this.socket = socket; } @Override public void run() { // TODO Auto-generated method stub BufferedReader socketIn = null; try { InputStream is = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(is); socketIn = new BufferedReader(isr); String inTemp = null; while(true){ inTemp = socketIn.readLine(); if(inTemp != null && !"bye".equals(inTemp) ){ System.out.println("好友:\n"+inTemp); }else{ System.out.println("好友:\n已下線,關閉當前回話"); break; } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { Thread.currentThread().interrupt(); socketIn.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
ok,簡單的sockte服務與客戶端完成了
先啟動server
在分別啟動client
輸入結束bye,關閉當前會話