Java SE实现多人聊天室功能 Java SE实现多人聊天室功能
L_X_Y_HH 人气:0实现功能:
1.实现用户注册上线,下线
2.实现群聊和私聊功能
3.实现统计当前在线人数
实现思路:
1.首先,要实现服务端与客户端之间的连接
这里是使用套接字建立TCP连接:
(1)服务器端先实例化一个描述服务器端口号的ServerSocket对象
(2)客户端要创建Socket对象来连接指定的服务器端
(3)服务器端调用ServerSocket类的accept()方法来监听连接到服务器端的客户端信息
(4)若服务器端与客户端连接成功,双方将返回一个Socket对象,此时双方可以进行通信
(5)服务器端与客户端使用I/O流进行连接,服务端的输出流连接客户端的输入流,客户端的输出流连接服务端的输入流
(6)使用close()方法关闭套接字(一定要记得关闭)
2.因为是拥有一个服务端来实现多个客户端的连接,此处还要解决的是多线程的问题。
每个客户端需要两个线程,来分别处理向服务端发送消息和向服务端接收消息
而服务端,当每增加一个客户端与服务端连接,服务端都要多创建一个线程来处理与客户端的连接
具体代码:
单线程实现:
客户端
import java.io.IOException; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; /** * @author LXY * @email 403824215@qq.com * @date 2018/7/20 15:46 */ //客户端 public class SingleClient { public static void main(String[] args) throws IOException { //客户端连接服务器,返回套接字Socket对象 Socket socket = new Socket("127.0.0.1",6666); //获取服务端的输出流,向服务器端输出内容 PrintStream printStream = new PrintStream(socket.getOutputStream()); printStream.println("我是客户端" + socket.getLocalPort()); //获取服务器端的输入流,读取服务器端的内容 Scanner scanner = new Scanner(socket.getInputStream()); scanner.useDelimiter("\n"); if(scanner.hasNext()) { System.out.println(scanner.next()); } //关闭流 socket.close(); } }
服务端
import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; /** * @author LXY * @email 403824215@qq.com * @date 2018/7/20 15:34 */ //服务端 public class SingleServer { public static void main(String[] args) throws IOException { //创建服务器端的ServerSocket对象,等待客户端进行连接 ServerSocket serverSocket = new ServerSocket(6666); System.out.println("服务器的端口号为6666,等待客户端连接。。。"); //侦听并接收服务器端的连接,返回套接字Socket对象 Socket socket = serverSocket.accept(); //获取客户端的输入流,读取客户端的输入内容 Scanner scanner = new Scanner(socket.getInputStream()); scanner.useDelimiter("\n"); if(scanner.hasNext()) { System.out.println("客户端发来消息:" + scanner.next()); } //获取客户端的输出流,向客户端输出内容 PrintStream printStream = new PrintStream(socket.getOutputStream()); printStream.println("客户端你好,我是服务器端:" + serverSocket.getLocalPort()); //关闭流 serverSocket.close(); } }
多线程实现
客户端
import java.io.IOException; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; /** * @author LXY * @email 403824215@qq.com * @date 2018/7/20 15:55 */ //客户端 //客户端读取服务器端信息的线程 class ClientReadServer implements Runnable { private Socket socket; public ClientReadServer(Socket socket) { this.socket = socket; } public void run() { try { Scanner scanner = new Scanner(socket.getInputStream()); while (scanner.hasNext()) { System.out.println(scanner.next()); } socket.close(); } catch (IOException e) { e.printStackTrace(); } } } //客户端向服务端发送信息的线程 class ClientSendServer implements Runnable { private Socket socket; public ClientSendServer(Socket socket) { this.socket = socket; } public void run() { try { PrintStream printStream = new PrintStream(socket.getOutputStream()); Scanner scanner = new Scanner(System.in); while (true) { String msg = null; if(scanner.hasNext()) { msg = scanner.next(); printStream.println(msg); } if(msg.equals("bye")) { scanner.close(); printStream.close(); break; } } } catch (IOException e) { e.printStackTrace(); } } } public class MultiClient { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.0.1",6666); Thread read = new Thread(new ClientReadServer(socket)); Thread send = new Thread(new ClientSendServer(socket)); read.start(); send.start(); } }
服务端
import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author LXY * @email 403824215@qq.com * @date 2018/7/20 16:12 */ class Server implements Runnable { private static Map<String,Socket> map = new ConcurrentHashMap<String, Socket>(); private Socket socket; public Server(Socket socket) { this.socket = socket; } public void run() { try { Scanner scanner = new Scanner(socket.getInputStream()); String msg = null; while (true) { if(scanner.hasNextLine()) { msg = scanner.nextLine(); Pattern pattern = Pattern.compile("\r"); Matcher matcher = pattern.matcher(msg); msg = matcher.replaceAll(""); //用户注册——格式:userName:用户名 if(msg.startsWith("userName:")) { String userName = msg.split("\\:")[1]; userRegist(userName,socket); continue; } //群聊——格式:G:群聊信息 else if(msg.startsWith("G:")) { firstStep(socket); String str = msg.split("\\:")[1]; groupChat(socket,str); continue; } else if(msg.startsWith("P:") && msg.contains("-")) { firstStep(socket); String userName = msg.split("\\:")[1].split("-")[0]; String str = msg.split("\\:")[1].split("-")[1]; privateChat(socket,userName,str); continue; } else if(msg.contains("bye")) { firstStep(socket); userExit(socket); continue; } else { PrintStream printStream = new PrintStream(socket.getOutputStream()); printStream.println("格式输入错误"); continue; } } } } catch (IOException e) { e.printStackTrace(); } } private void firstStep(Socket socket) throws IOException { Set<Map.Entry<String,Socket>> set = map.entrySet(); for(Map.Entry<String,Socket> entry:set) { if(entry.getValue().equals(socket)) { if(entry.getValue() == null) { PrintStream printStream = new PrintStream(socket.getOutputStream()); printStream.println("请先进行注册操作!格式为:[userName:用户名]"); } } } } private void userRegist(String userName, Socket socket) { map.put(userName,socket); System.out.println("用户名:" + userName + "客户端" + socket +"上线了!!"); System.out.println("当前在线人数为" + map.size() + "人"); } private void groupChat(Socket socket, String msg) throws IOException { Set<Map.Entry<String,Socket>> set = map.entrySet(); String userName = null; for(Map.Entry<String,Socket> entry:set) { if(entry.getValue().equals(socket)) { userName = entry.getKey(); break; } } for(Map.Entry<String,Socket> entry:set) { Socket client = entry.getValue(); PrintStream printStream = new PrintStream(client.getOutputStream()); printStream.println(userName + "说" + msg); } } private void privateChat(Socket socket, String userName, String msg) throws IOException { String curUser = null; Set<Map.Entry<String,Socket>> set = map.entrySet(); for(Map.Entry<String,Socket> entry:set) { if(entry.getValue().equals(socket)) { curUser = entry.getKey(); break; } } Socket client = map.get(userName); PrintStream printStream = new PrintStream(client.getOutputStream()); printStream.println(curUser + "私聊说" + msg); } private void userExit(Socket socket) { String userName = null; for(String key:map.keySet()) { if(map.get(key).equals(socket)) { userName = key; break; } } map.remove(userName,socket); System.out.println("用户" + userName + "已下线"); } } public class MultiServer { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(6666); //使用线程池 ExecutorService executorService = Executors.newFixedThreadPool(20); for(int i = 0;i < 20;i++) { System.out.println("欢迎来到聊天室。。。"); Socket socket = serverSocket.accept(); System.out.println("新人加入。。。"); executorService.execute(new Server(socket)); } executorService.shutdown(); serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }
加载全部内容