客户端:
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
//读取服务器发来的消息
class ReadThread implements Runnable {
private Socket client;
public ReadThread(Socket client) {
this.client = client;
}
@Override
public void run() {
//获取客户端输入流
try {
Scanner in =new Scanner(client.getInputStream());
in.useDelimiter("\n");
while (true){
if(in.hasNextLine()){
System.out.printf("从服务端发来的消息为:"+in.nextLine());
}
if (client.isClosed()){
System.out.printf("客户端i关闭");
break;
}
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//给服务器发送消息
class WriterThread implements Runnable{
private Socket client;
public WriterThread(Socket client) {
this.client = client;
}
@Override
public void run() {
//获取键盘输入
Scanner scanner=new Scanner(System.in);
scanner.useDelimiter("\n");
//获取客户端输出流
try {
PrintStream out=new PrintStream(client.getOutputStream());
while(true){
System.out.printf("请输入发送消息:");
String strToServer;
if(scanner.hasNextLine()){
strToServer=scanner.nextLine();
out.println(strToServer);
//客户端退出标志
if (strToServer.equals("byebye")){
System.out.printf("关闭客户端");
scanner.close();
out.close();
client.close();
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class mulThreadClient {
public static void main(String[] args) {
try {
Socket client=new Socket("127.0.0.1",6666);
Thread readThread=new Thread(new ReadThread(client));
Thread writerThread=new Thread(new WriterThread(client));
readThread.start();
writerThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器:
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;
public class mulThreadServer {
//存储所有注册的客户端
private static Map clientMap = new ConcurrentHashMap();
//具体处理与每个客户端通信的内部类
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 strFormClient;
while (true) {
if (in.hasNextLine()) {
strFormClient = in.nextLine();
Pattern pattern = Pattern.compile("\r");
Matcher matcher = pattern.matcher(strFormClient);
strFormClient = matcher.replaceAll("");
//注册
if (strFormClient.startsWith("userName")) {
String userName = strFormClient.split("\\:")[1];
registerCilent(userName, client);
continue;
}
//群聊
if (strFormClient.startsWith("G")){
String msg=strFormClient.split("\\:")[1];
groupChat(msg);
}
//私聊
if (strFormClient.startsWith("P")){
String userName=strFormClient.split("\\:")[1].split("-")[0];
String msg=strFormClient.split("\\:")[1].split("-")[1];
privateChat(userName,msg);
}
//用户退出
if (strFormClient.contains("byebye")){
String userName=null;
for (String keyName:clientMap.keySet()){
if (clientMap.get(keyName).equals(client)){
userName=keyName;
}
}
System.out.printf("用户"+userName+"下线了\n");
clientMap.remove(userName);
System.out.println("当前用户数为"+(clientMap.size())+"\n");
continue;
}
}
}
} catch (IOException e) {
System.err.println("服务器通信异常,错误"+e);
}
}
//注册方法
private void registerCilent(String userName, Socket client) {
System.out.println("用户姓名" + userName);
System.out.println("用户" + userName + "上线了\n");
System.out.println("当前群聊人数" + (clientMap.size()+1) + "人\n");
clientMap.put(userName, client);
try {
PrintStream out = new PrintStream(client.getOutputStream(),true,"UTF-8");
out.println("用户注册成功");
} catch (IOException e) {
e.printStackTrace();
}
}
//群聊流程
private void groupChat(String msg) {
//取出clientMap中所有的Entry遍历发送群聊消息
Set> clientSet = clientMap.entrySet();
for (Map.Entry entry : clientSet) {
try {
Socket socket = entry.getValue();
PrintStream out = new PrintStream(socket.getOutputStream(), true, "UTF-8");
out.println("群聊消息为:" + msg + "\n");
} catch (IOException e) {
System.err.println("群聊异常,错误为" + e);
}
}
}
//私聊流程
private void privateChat(String userName, String msg) {
Socket privateScoket=clientMap.get(userName);
try {
PrintStream out=new PrintStream(privateScoket.getOutputStream(),true,"UTF-8");
out.println("私聊消息为:"+msg+"\n");
} catch (IOException e) {
System.out.println("私聊异常,错误为"+e);
}
}
}
public static void main(String[] args) throws Exception {
ExecutorService executorService=Executors.newFixedThreadPool(20);
ServerSocket serverSocket=new ServerSocket(6666);
for(int i=0;i<20;i++){
System.out.println("等待客户端连接。。\n");
Socket client=serverSocket.accept();
System.out.println("有新的客户端连接,端口号为:"+client.getPort()+"\n");
executorService.submit(new ExecuteClient(client));
}
executorService.shutdown();
serverSocket.close();
}
}