标签:
运用Java套接字我们几乎可以完成一个网络聊天软件的小产品,本文不涉及UI部分,仅对原理部分用代码演示一下。一个可以多人聊天的小功能,在Linux系统上用telnet亲测可用。
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(); } } } } }
标签:
原文地址:http://my.oschina.net/zzw922cn/blog/490959