等一个大佬告诉我这波服务器资源怎么释放 …
服务器驱动类
package cn.hyo.day9.ChatRoom;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
@author weng
@build 2020年7月27日 下午2:54:31
TODO 服务器端
*/
//服务器资源释放难度有点大
public class TriggerServer { //服务器驱动类
private static CopyOnWriteArrayList<RDWRChannel> list;
private static ServerSocket server_socket;
private static ExecutorService pool;
public static void main(String[] args) throws Exception {
init();
while(true) {
Socket client = server_socket.accept();
RDWRChannel channel = new RDWRChannel(client);
pool.execute(channel);
list.add(channel);
System.out.println("用户:"+channel.name+"连接成功");
channel.SendToClient(channel.name+"进入了聊天室", true);
}
}
private static void init() throws Exception {
server_socket =new ServerSocket(9999);
list =new CopyOnWriteArrayList<RDWRChannel>();
pool =Executors.newCachedThreadPool(); //带缓存的线程池
}
static class RDWRChannel implements Runnable{ //服务器端读写通道
private Socket socket;
private DataInputStream receiver;
private DataOutputStream sender;
private String name;
public RDWRChannel(Socket socket) throws Exception {
super();
this.socket = socket;
receiver =new DataInputStream(socket.getInputStream());
sender =new DataOutputStream(socket.getOutputStream());
this.name =receiveFromClient();
}
private String receiveFromClient() throws Exception {return receiver.readUTF();}
private void SendToClient(String s ,boolean isSys) throws Exception {
String[] spl =analysisInfo(s);
if(!spl[0].equals("")) { //私信
for(RDWRChannel channel :list) if(channel.name.equals(spl[0])) {channel.SendToClientOne(this.name+"悄悄地对您说:"+spl[1]);}
}else { //群发
if(isSys) {
s ="<系统提示>"+spl[1]+"<系统提示>";
}else {
s =this.name+":"+spl[1];
}
for(RDWRChannel channel :list) channel.SendToClientOne(s);
}
}
private void release() throws Exception {QuickRelease.release(socket ,receiver ,sender);}
private void quit() throws Exception { list.remove(this);System.out.println("用户"+this.name+"连接切断"); SendToClient(this.name+"退出了聊天室", true); Thread.sleep(500); release();}
private void SendToClientOne(String s) throws Exception {sender.writeUTF(s);}
private String[] analysisInfo(String s) {
String[] spl =new String[2];
if(s.startsWith("@")) {
spl[0] =s.substring(1 ,s.indexOf(":"));
spl[1] =s.substring(s.indexOf(":") +1);
return spl;
}
spl[0] ="";
spl[1] =s;
return spl;
}
@Override
public void run() {
while(true) {
try {
String s =receiveFromClient();
if(s.equals("quit")) {SendToClientOne("quit"); break;} else SendToClient(s, false);
} catch (Exception e) {
e.printStackTrace();
try {
release();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
try {
quit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
客户端驱动类
package cn.hyo.day9.ChatRoom;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
/*
@author weng
@build 2020年7月27日 下午2:54:47
TODO 客户端驱动类
*/
public class TriggerClient {
private static Socket socket;
private static BufferedReader console;
public static void main(String[] args) throws Exception {
init();
System.out.println("<系统提示>请输入您的昵称<系统提示>");
String uname = console.readLine().trim();
WRChannelClient wrChannelClient = new WRChannelClient(socket.getOutputStream() ,uname);
RDChannelClient rdChannelClient = new RDChannelClient(socket.getInputStream());
Thread wrThread = new Thread(wrChannelClient);
Thread rdThread = new Thread(rdChannelClient);
wrThread.start();
rdThread.start();
while(true) if(!rdThread.isAlive()) break;
release();
System.out.println("客户端资源释放完成");
}
private static void release() throws Exception { QuickRelease.release(console ,socket);}
private static void init() throws Exception {
socket = new Socket("localhost" ,9999);
console = new BufferedReader(new InputStreamReader(System.in));
}
}
客户端 读通道
package cn.hyo.day9.ChatRoom;
/*
@author weng
@build 2020年7月27日 下午3:32:04
TODO 客户端 读通道
*/
import java.io.DataInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class RDChannelClient implements Runnable{
private InputStream input_socket;
private DataInputStream receiver;
private SimpleDateFormat time;
public RDChannelClient(InputStream input_socket) throws Exception {
super();
this.input_socket = input_socket;
receiver =new DataInputStream(this.input_socket);
time =new SimpleDateFormat("MM-dd hh:mm");
}
private String receiveFromServer() throws Exception {return receiver.readUTF();}
void release() throws Exception {System.out.println("尝试关闭读通道"); QuickRelease.release(input_socket ,receiver);}
@Override
public void run() {
while(true) {
try {
String s =receiveFromServer();
if(s.equals("quit")) break; else {System.out.println(time.format(new Date())); System.out.println(s);}
} catch (Exception e) {
e.printStackTrace();
try {
release();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
try {
release();
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端 写通道
package cn.hyo.day9.ChatRoom;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
/*
@author weng
@build 2020年7月27日 下午3:32:13
TODO 客户端 写通道
*/
public class WRChannelClient implements Runnable{
private OutputStream output_socket;
private String uname;
private BufferedReader console;
private DataOutputStream sender;
private boolean isRunning =true;
public boolean getIsRunning() {return isRunning;}
public WRChannelClient(OutputStream output_socket, String uname) throws Exception {
super();
this.uname = uname;
this.output_socket =output_socket;
console =new BufferedReader(new InputStreamReader(System.in));
sender =new DataOutputStream(this.output_socket);
sendToServer(this.uname);
}
String getFromConsole() throws Exception {return console.readLine().trim();}
void sendToServer(String s) throws Exception {sender.writeUTF(s); sender.flush();}
void release() throws Exception {System.out.println("尝试关闭写通道"); QuickRelease.release(console ,output_socket ,sender);}
@Override
public void run() {
while(true) {
try {
String s =getFromConsole();
if(!s.equals("")) {
sendToServer(s);
if(s.equals("quit")) break;
}
} catch (Exception e) {
e.printStackTrace();
try {
release();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
try {
release();
} catch (Exception e) {
e.printStackTrace();
}
}
}
资源释放类
public class QuickRelease {
static void release(Closeable ...clo) throws Exception {
for(Closeable c :clo) if(c !=null) c.close();
}
}