需求:
分割线----------------------------------------------------------------------------------------------------------------分割线
代码:
Server:服务器类
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
/*
* 服务器端程序
*/
public class Server {
// 客户端的昵称
private static Character name = 64;
// 客户端的输出流与昵称的Map关系
private Map<PrintWriter, Character> map = null;
// 服务器Socket
private ServerSocket serverSocket = null;
// 线程池
private ExecutorService pool = null;
// 构造方法,用于初始化
public Server() {
super();
try {
serverSocket = new ServerSocket(8888);
map = new HashMap<PrintWriter, Character>();
pool = Executors.newFixedThreadPool(10);
} catch (IOException e) {
e.printStackTrace();
}
}
// 服务端开启方法
public void start() {
Socket socket = null;
try {
// 监听客户端
while (true) {
System.out.println("等待客户端连接……");
socket = serverSocket.accept();// accept()是阻塞方法
System.out.println("客户端已连接!");
// 启动一个线程去处理该客户端的请求
ClientHandler clientHandler = new ClientHandler(socket);
pool.execute(clientHandler);
name++;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
Util.shut(null, null, null, null, null, socket);
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
System.out.println("ServerSocket已关闭");
}
}
}
}
// 内部类
// 线程类,用户处理客户端请求
private class ClientHandler implements Runnable {
private Socket socket = null;
public ClientHandler(Socket socket) {
super();
this.socket = socket;
}
@Override
public void run() {
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferReader = null;
OutputStream outputStream = null;
OutputStreamWriter outputStreamWriter = null;
PrintWriter printWriter = null;
try {
// 获取客户端消息
inputStream = socket.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
bufferReader = new BufferedReader(inputStreamReader);
// 获取客户端输出流
outputStream = socket.getOutputStream();
outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
printWriter = new PrintWriter(outputStreamWriter, true);
// 将客户端的输出流保存到Map中
addMap(printWriter, name);
System.out.println("当前连接的客户端数:" + map.size());
sendMap(socket);
boolean isOk = true;
String message = bufferReader.readLine();
while (isOk) {
// 判断客户端是否选择退出
if ("exit".equalsIgnoreCase(message) || message == null) {
isOk = false;
String notice = "客户端" + map.get(printWriter) + "/" + socket.getInetAddress() + "与服务器断开连接!";
System.out.println(notice);
sendList(printWriter, notice);
// 从Map中移除此客户端
removeMap(printWriter);
System.out.println("当前连接的客户端数:" + map.size());
sendMap(socket);
} else {
// 遍历所有输出流
do {
message = map.get(printWriter).toString() + "/" + socket.getInetAddress() + ":" + message;
sendList(printWriter, message);
} while ((message = bufferReader.readLine()) != null);
}
}
} catch (SocketException e) {
System.out.println("客户端" + map.get(printWriter) + "/" + socket.getInetAddress() + "与服务器断开连接!");
// 从Map中移除此线程
removeMap(printWriter);
System.out.println("当前连接的客户端数:" + map.size());
sendMap(socket);
}
catch (IOException e) {
e.printStackTrace();
} finally {
// 从Map中移除此客户端
removeMap(printWriter);
// 关闭资源
Util.shut(bufferReader, inputStreamReader, outputStreamWriter, inputStream, outputStream, socket);
}
}
// 添加同步方法
private synchronized void addMap(PrintWriter printWriter, Character name) {
map.put(printWriter, name);
}
// 移除同步方法
private synchronized void removeMap(PrintWriter printWriter) {
map.remove(printWriter);
}
// 打印同步方法
private synchronized void sendMap(Socket socket) {
Set<PrintWriter> set = map.keySet();
if (map.size() != 0) {// 当Map中还有元素,则打印元素内容
for (PrintWriter printWriter : set) {
System.out.println(map.get(printWriter) + "/" + socket.getInetAddress());
}
}
}
// 输出同步方法
private synchronized void sendList(PrintWriter printWriter, String message) {
Set<PrintWriter> set = map.keySet();
for (PrintWriter pw : set) {
if (pw != printWriter) {
pw.println(message);
}
}
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
}
Client:客户端类
import java.io.*;
import java.net.*;
import java.util.*;
/*
* 客户端程序
*/
public class Client {
// 客户端Socket
private Socket socket;
// 构造方法,用于初始化
public Client() {
super();
try {
socket = new Socket("localhost", 8888);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// 客户端工作方法
public void start() {
OutputStream outputStream = null;
OutputStreamWriter outputStreamWriter = null;
PrintWriter printWriter = null;
Scanner scanner = null;
try {
// 启动接收服务器信息的线程
ServerHandler serverHandler = new ServerHandler(socket);
Thread thread = new Thread(serverHandler);
thread.setDaemon(true);// 设置为守护线程
thread.start();
outputStream = socket.getOutputStream();
outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
printWriter = new PrintWriter(outputStreamWriter, true);
// 读取用户输入的内容
scanner = new Scanner(System.in);
while (true) {
String string = scanner.nextLine();
printWriter.println(string);
// 如果用户输入exit,则退出循环
if ("exit".equalsIgnoreCase(string)) {
System.out.println("您已成功断开与服务器的连接");
break;
}
}
} catch (ConnectException e) {
System.out.println("服务器未启动,请先启动服务器");
} catch (SocketException e) {
System.out.println("与服务器失去联系");
} catch (IOException e) {
System.out.println("发生IO异常");
} finally {
Util.shut(null, null, outputStreamWriter, null, outputStream, socket);
if (scanner != null) {
scanner.close();
}
}
}
private class ServerHandler implements Runnable {
private Socket socket;
public ServerHandler(Socket socket) {
super();
this.socket = socket;
}
@Override
public void run() {
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferReader = null;
try {
inputStream = socket.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
bufferReader = new BufferedReader(inputStreamReader);
while (true) {
System.out.println(bufferReader.readLine());
}
} catch (SocketException e) {
System.out.println("与服务器断开连接");
} catch (Exception e) {
e.printStackTrace();
} finally {
Util.shut(bufferReader, inputStreamReader, null, inputStream, null, socket);
}
}
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}
}
Util:工具类
import java.io.*;
import java.net.*;
class Util {
static void shut(BufferedReader bufferReader, InputStreamReader inputStreamReader,OutputStreamWriter outputStreamWriter, InputStream inputStream, OutputStream outputStream, Socket socket) {
if (bufferReader != null) {
try {
bufferReader.close();
} catch (IOException e) {
System.out.println("BufferReader已关闭");
}
}
if (inputStreamReader != null) {
try {
inputStreamReader.close();
} catch (IOException e) {
System.out.println("InputStreamReader已关闭");
}
}
if (outputStreamWriter != null) {
try {
outputStreamWriter.close();
} catch (IOException e) {
System.out.println("OutputStreamWriter已关闭");
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
System.out.println("InputStream已关闭");
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
System.out.println("OutputStream已关闭");
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
System.out.println("Socket已关闭");
}
}
}
}