功能:
监听端口:30000;
通过客户端IP地址判断该客户端是否已经连接,若已经连接就删除掉原来的Socket,重新建立连接;
有客户端连接后自动发送一送一条"已连接 "给该客户端;
对收到消息判断是否为空格组成或其他制表符等的无意义字段,对含有有意义字符的广播给所有客户端;
[MySocketServer.java]:
1 import java.io.IOException; 2 import java.net.ServerSocket; 3 import java.net.Socket; 4 import java.util.ArrayList; 5 6 @SuppressWarnings("resource") 7 public class MySocketServer { 8 // 定义保存所有Socket的ArrayList 9 public static ArrayList<Socket> socketList = new ArrayList<Socket>(); 10 public static ArrayList<String> ipList = new ArrayList<String>(); 11 12 public static void main(String args[]) throws IOException { 13 ServerSocket ss = new ServerSocket(30000); 14 while (true) { 15 // 此行代码会阻塞,一直等待别人的连接 16 Socket s = ss.accept(); 17 18 String ip = s.getInetAddress().toString(); 19 ip = s.getInetAddress().toString(); 20 if (ipList.size() == 0) { 21 System.out.println("提醒:" + ip + " 用户连接到服务器!"); 22 } 23 for (int i = 0; i < ipList.size(); i++) { 24 if (ip.equals(ipList.get(i))) { 25 ipList.remove(i); 26 socketList.remove((i)); 27 System.out.println("提醒:" + ip + " 用户已重新连接到服务器!"); 28 } else { 29 System.out.println("提醒:" + ip + " 用户连接到服务器!"); 30 } 31 } 32 33 ipList.add(ip); 34 socketList.add((s)); 35 // 每当一个客户端连接后,启动一个ServerThread线程为该客户端服务 36 new Thread(new ServerThread(s)).start(); 37 } 38 } 39 }
[ServerThread.java]:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.net.SocketException; 4 import java.io.InputStreamReader; 5 import java.io.OutputStream; 6 import java.net.Socket; 7 8 // 负责处理每个线程通信的线程类 9 public class ServerThread implements Runnable { 10 // 定义当前线程要处理的Socket 11 Socket s = null; 12 // 该线程处理的Socket对应的输入输出流 13 BufferedReader br = null; 14 int n = 0; 15 16 public ServerThread(Socket s) throws IOException { 17 this.s = s; 18 // 初始化该Socket对应的输入输出流 19 br = new BufferedReader(new InputStreamReader(s.getInputStream(), 20 "utf-8")); 21 } 22 23 public void run() { 24 try { 25 if (n == 0) { 26 OutputStream osGuangBo = s.getOutputStream(); 27 osGuangBo.write(("已连接 ").getBytes("utf-8")); 28 } 29 String content = null; 30 // 采用循环不断从Socket中读取客户端发送过来的数据 31 while ((content = br.readLine()) != null) { 32 /* 33 * 当收到的字符串不是空或无意义的空格、TAB制表符的时候 34 * 才进行处理;String.trim().isEmpty()去掉前导空白和后 导空白,再判断是否为空; 35 */ 36 if (!content.trim().isEmpty()) { 37 System.out.println("收到:" + content); 38 39 // 告知客户端已收到消息 40 // OutputStream os = s.getOutputStream(); 41 // os.write("SUCESS".getBytes("utf-8")); 42 43 // 遍历socketList中的每个Socket,将内容向每个Socket发送一次 44 for (Socket s : MySocketServer.socketList) { 45 // 不能声明在for循环外部,否则输出流就只是主线程传进来的那一个,导致广播的消息都给了那一个socket 46 OutputStream osGuangBo = s.getOutputStream(); 47 osGuangBo.write(("广播:" + content + " ") 48 .getBytes("utf-8")); 49 } 50 } 51 } 52 } catch (SocketException e) { 53 System.out.println("Socket Reset!"); 54 // 删除该Socket 55 MySocketServer.socketList.remove(s); 56 } catch (IOException e) { 57 e.printStackTrace(); 58 } 59 } 60 }