项目描述
支持登录,退出,私聊,群聊。
使用技术
Java基础
多线程
Socket编程
服务端代码
package com.github7.Server;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MultServer {
private static final Map<String, Socket> Online_Client = new ConcurrentHashMap<>();
public static void main(String[] args) {
try {
//创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
//创建服务端口号
ServerSocket serverSocket = new ServerSocket(65535);
for (int i = 0; i < 10; i++) {
//客户端连接
Socket client = serverSocket.accept();
System.out.println("客户端连接成功,地址为" + client.getInetAddress());
executorService.submit(new ExecuteClient(client));
}
} catch (IOException e) {
e.printStackTrace();
}
}
//处理客户端的信息 实现功能
public static class ExecuteClient implements Runnable {
private Socket client;
public ExecuteClient(Socket client) {
this.client = client;
}
@Override
public void run() {
try {
InputStream clientInput = client.getInputStream();
Scanner scanner = new Scanner(clientInput);
while (true) {
//按行读取消息,截取内容,获取响应功能
String message = scanner.nextLine();
/*
1.登录login:name
2.私聊chat:name:content
3.群聊chats:content
4.退出exit:name
*/
String[] array = message.split(":");
if ("login".equals(array[0])) {
String loginName = array[1];
loginFunction(loginName);
continue;
} else if ("chat".equals(array[0])) {
String toName = array[1];
String content = array[2];
chatFunction(toName, content);
continue;
} else if ("chats".equals(array[0])) {
String alluserMessage = array[1];
chatsFunction(alluserMessage);
continue;
} else if ("exit".equals(array[0])) {
String exitName = array[1];
exitFunction(exitName);
continue;
} else {
sendMessageToClient(this.client, "发送消息失败,请检查格式", false);
continue;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void sendMessageToClient(Socket toclient, String mess, boolean sendfix) {
try {
OutputStream outputStream = null;
outputStream = toclient.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(outputStream);
String sendFrom = "";
for (Map.Entry<String, Socket> entry : Online_Client.entrySet()) {
if (entry.getValue().equals(this.client)) {
sendFrom = entry.getKey();
}
}
//群发自己也可以收到
if (sendfix == true) {
writer.write(sendFrom + "(群发)-->" + mess + "\n");
} else {
writer.write(sendFrom+"-->"+mess + "\n");
}
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void loginFunction(String loginName) throws IOException {
boolean hasLogin = false;
for (Map.Entry<String, Socket> entry : Online_Client.entrySet()) {
if (entry.getKey().equals(loginName)) {
hasLogin = true;
this.sendMessageToClient(this.client, loginName + "Error!!! 账号重复登录。", false);
printOnlineClient();
break;
}
}
if (hasLogin == false) {
Online_Client.put(loginName, this.client);
printOnlineClient();
this.sendMessageToClient(this.client, loginName + "登录成功", false);
}
}
//私聊用户
private void chatFunction(String toName, String content) throws IOException {
//获取Map中保存的用户进程
Socket toClient = Online_Client.get(toName);
if (toClient == null) {
this.sendMessageToClient(this.client, "发送失败,对方没有注册", false);
} else {
this.sendMessageToClient(toClient, content, false);
}
}
//群聊功能
private void chatsFunction(String alluserMessage) throws IOException {
for (Map.Entry<String, Socket> entry : Online_Client.entrySet()) {
Socket toClient = entry.getValue();
if (!toClient.equals(this.client)) {
this.sendMessageToClient(toClient, alluserMessage, true);
}
}
}
//退出功能的实现
private void exitFunction(String exitName) {
for (Map.Entry<String, Socket> entry : Online_Client.entrySet()) {
//只能自己退出
if (entry.getValue().equals(this.client)) {
Online_Client.remove(entry.getKey());
}
}
printOnlineClient();
}
//打印在线用户
private void printOnlineClient() {
System.out.println("已经登录用户如下:");
for (String clienName : Online_Client.keySet()) {
System.out.println("用户名-->" + clienName);
}
}
}
}