運用Java套接字咱們幾乎能夠完成一個網絡聊天軟件的小產品,本文不涉及UI部分,僅對原理部分用代碼演示一下。一個能夠多人聊天的小功能,在Linux系統上用telnet親測可用。 java
package demo0811.demo3; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 使用多線程寫一個服務器,端口號爲9999 * @author zzw * */ public class ServerMain { public static ArrayList<Integer> ports=new ArrayList<Integer>(); public static ArrayList<OutputStream> streams=new ArrayList<OutputStream>(); public static void main(String[] args) { try(ServerSocket server=new ServerSocket(9999)) { System.out.println("服務器正在運行"); ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(50); while(true) { Socket socket = server.accept(); int port = socket.getPort(); OutputStream outputStream = socket.getOutputStream(); ports.add(port); streams.add(outputStream); newFixedThreadPool.submit(new SocketRunnable(socket,outputStream)); newFixedThreadPool.submit(new NotifyNewersRunnable(port)); } } catch (Exception ex) { System.out.println("沒法創建監聽服務!"); ex.printStackTrace(); } } }
package demo0811.demo3; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.Socket; import java.util.Date; public class SocketRunnable implements Runnable { private Socket socket; private OutputStream outputStream; public SocketRunnable(Socket socket,OutputStream outputStream) { this.socket=socket; this.outputStream=outputStream; } @Override public void run() { try { OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); Date date = new Date(); outputStreamWriter.write(date.toString()+"\n如發私信,請使用[port]開頭"+"\r\n"); outputStreamWriter.flush(); int port = socket.getPort(); while(true) { if(socket.isConnected()) { InputStream inputStream = socket.getInputStream(); InputStreamReader reader = new InputStreamReader(inputStream,"UTF-8"); BufferedReader bufferedReader = new BufferedReader(reader); String line; while((line=bufferedReader.readLine())!=null) { if(line.startsWith("[")) { int end=line.indexOf(']'); int target=Integer.parseInt(line.substring(1, end)); int indexOf = ServerMain.ports.indexOf(target); if(end<0||indexOf<0) { OutputStreamWriter outputStreamWriter2 = new OutputStreamWriter(ServerMain.streams.get(ServerMain.ports.indexOf(port)),"UTF-8"); outputStreamWriter2.write("您的私信格式輸入有誤或端口號不存在!\r\n"); outputStreamWriter2.flush(); } else { OutputStreamWriter outputStreamWriter2 = new OutputStreamWriter(ServerMain.streams.get(indexOf),"UTF-8"); outputStreamWriter2.write("端口"+port+"私信:"+line.substring(end+1)+"\r\n"); outputStreamWriter2.flush(); } } else { for(int i=0;i<ServerMain.streams.size();i++) { try { OutputStreamWriter outputStreamWriter2 = new OutputStreamWriter(ServerMain.streams.get(i),"UTF-8"); outputStreamWriter2.write("端口"+port+"羣聊:"+line+"\n"); outputStreamWriter2.flush(); } catch (IOException e) { e.printStackTrace(); } } } } } else { break; } } socket.close(); } catch (IOException e) { System.out.println("服務器沒法向客戶端寫入數據!"); e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { //不處理 } } } }
package demo0811.demo3; import java.io.IOException; public class NotifyNewersRunnable implements Runnable{ private int port; public NotifyNewersRunnable(int port) { this.port = port; } @Override public void run() { int n; String str="端口"+port+"上線了\r\n"; if((n=ServerMain.streams.size())>1) { for(int i=0;i<n-1;i++) { try { ServerMain.streams.get(i).write(str.getBytes("utf-8")); ServerMain.streams.get(i).flush(); } catch (IOException e) { e.printStackTrace(); } } } } }