版权声明:禁止侵权,打击盗版! https://blog.csdn.net/ChenGX1996/article/details/82420545
该聊天系统实现了Java多线程之间互相通信;
该程序中最多创建10个线程,可选择上线、群聊、私聊、下线等功能;
服务器端:
package talkingplus;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;
import java.util.Map.Entry;
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;
/**
* 多线程聊天室服务器端
*/
public class MultiThreadServer {
//存储所有注册的客户端
private static Map<String,Socket> clientMap = new ConcurrentHashMap<String, Socket>();
//具体处理与每个客户端通信的内部类
private static class ExecuteClient implements Runnable {
private Socket client;
public ExecuteClient(Socket client){
this.client = client;
}
@Override
public void run() {
try {
//获取客户端输入流
Scanner in = new Scanner(client.getInputStream());
String strFromClient;
while(true){
if(in.hasNextLine()){
strFromClient = in.nextLine();
//windows下将默认换行中\r\n中的\r替换为空字符串
Pattern pattern = Pattern.compile("\r");
Matcher matcher = pattern.matcher(strFromClient);
strFromClient = matcher.replaceAll("");
//注册流程
if(strFromClient.startsWith("注册")){
String UserName = strFromClient.split("\\:")[1];
//注册方法
zhuCe(UserName,client);
continue;
}
if(strFromClient.startsWith("群聊")){
String msg = strFromClient.split("\\:")[1];
//群聊
groupChat(msg);
continue;
}
if(strFromClient.startsWith("私聊")){
//要进行通信的用户名
String userName = strFromClient.split("\\:")[1].split(":")[0];
//要发送的内容
String msg = strFromClient.split("\\:")[1].split(":")[1];
//私聊
privateChat(strFromClient,msg);
continue;
}
if(strFromClient.startsWith("bye")){
String userName = null;
//根据Socket找到UserName
for (String keyName : clientMap.keySet()) {
if(clientMap.get(keyName).equals(client)){
userName = keyName;
}
}
System.out.println("用户"+userName+"下线!");
System.out.println("当前群聊人数为:"+(clientMap.size()-1)+"人");
clientMap.remove(userName);
continue;
}
}
}
} catch (IOException e) {
System.out.println("服务器异常!"+e); }
}
}
//注册方法
private static void zhuCe(String userName, Socket client){
System.out.println("用户姓名为:"+userName);
System.out.println("用户"+userName+"上线了");
System.out.println("当前群聊人数为:"+(clientMap.size()+1)+"人");
//将用户信息保存到map中
clientMap.put(userName,client);
try {
PrintStream out = new PrintStream(client.getOutputStream(),true,"UTF-8");
//告知用户 注册成功
out.println("注册成功!");
out.println("请尽情畅聊吧");
} catch (IOException e) {
e.printStackTrace();
}
}
//群聊流程
private static void groupChat(String msg){
//取出所有clientMap中所有Entry遍历发送群聊信息
Set<Map.Entry<String,Socket>> clientSet = clientMap.entrySet();
for(Map.Entry<String,Socket>entry : clientSet){
Socket socket = entry.getValue();
//取得每个客户的的输出流
try {
PrintStream out = new PrintStream(socket.getOutputStream(),true,"UTF-8");
out.println("群聊信息为:"+msg);
} catch (IOException e) {
System.out.println("群聊异常:"+e);
}
}
}
//私聊流程
private static void privateChat(String userName,String msg) {
Socket socket = clientMap.get(userName);
try {
PrintStream out = new PrintStream(socket.getOutputStream(), true, "UTF-8");
out.println("私聊信息为:" + msg);
} catch (IOException e) {
System.out.println("私聊异常:" + e);
}
}
public static void main(String[] args) throws IOException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
ServerSocket serverSocket = new ServerSocket(3366);
for(int i=0;i<10;i++){
System.out.println("等待客户端连接...");
Socket client = serverSocket.accept();
System.out.println("有新的客户端连接,端口号为:"+client.getPort());
executorService.submit(new ExecuteClient(client));
}
executorService.shutdown();
serverSocket.close();
}
}
客户端:
package talkingplus;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
/**
* 读取服务器信息线程
*/
class ReadFromServerThread implements Runnable {
private Socket client;
ReadFromServerThread(Socket client) {
this.client = client;
}
@Override
public void run() {
try {
Scanner in = new Scanner(client.getInputStream());
while(true){
if(in.hasNextLine()){
System.out.println("系统消息:"+in.nextLine());
}
//客户端退出
if(client.isClosed()){
System.out.println("您已成功下线!欢迎您下次再来:)");
break;
}
}
in.close();
} catch (IOException e) {
System.out.println("客户端读入信息失败!"); }
}
}
/**
* 给服务器发消息
*/
class WriteToServer implements Runnable {
private Socket client;
public WriteToServer(Socket client){
this.client = client;
}
@Override
public void run() {
try {
//获取键盘输入
Scanner in = new Scanner(System.in);
//获取客户端输出流
System.out.println("欢迎来到海内天涯聊天室☎☎☎" +
"\n注册请输入:注册\\:+用户名" +
"\n 群聊请输入:群聊\\:+消息" +
"\n 私聊请输入:私聊\\:+私聊对象:+消息" +
"\n下线请输入:包含bye的任意消息" );
PrintStream out = new PrintStream(client.getOutputStream());
while(true){
System.out.println("请输入消息:");
String string;
if(in.hasNextLine()){
string = in.nextLine();
out.println(string);
//客户端退出标志
if(string.contains("bye")){
System.out.println("客户端退出");
in.close();
out.close();
client.close();
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 多线程聊天室客户端
*/
public class MultiThreadClient {
public static void main(String[] args){
try {
Socket client = new Socket("127.0.0.1",3366);
//读取消息线程
Thread readFromServer = new Thread(new ReadFromServerThread(client));
//写入消息线程
Thread writeToServer = new Thread(new WriteToServer(client));
readFromServer.start();
writeToServer.start();
} catch (IOException e) {
System.out.println("客户端异常:"+e);
}
}
}
运行服务器:
运行客户端:
运行若干客户端:
注册、发送消息;
欢迎加入《海内天涯》测试...