public class Chat {
private static CopyOnWriteArrayList<Channel> all = new CopyOnWriteArrayList<Channel>();
public static void main(String[] args) throws IOException {
System.out.println("-----Server-----");
ServerSocket server = new ServerSocket(9999);
while (true) {
Socket client = server.accept();
System.out.println("一个客户端建立了连接");
Channel c = new Channel(client);
all.add(c);
new Thread(c).start();
}
}
static class Channel implements Runnable {
private DataOutputStream dos;
private DataInputStream dis;
private Socket client;
private boolean isRunning;
private String name;
public Channel(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
isRunning = true;
this.name = receive();
this.send("欢迎你的到来");
sendOthers(this.name + "来到了聊天室", true);
} catch (IOException e) {
System.out.println("-----构建出错-----");
release();
}
}
private String receive() {
String msg = "";
try {
msg = dis.readUTF();
} catch (IOException e) {
System.out.println("-----接收出错-----");
release();
}
return msg;
}
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
System.out.println("-----发送出错-----");
release();
}
}
private void sendOthers(String msg, boolean isSys) {
boolean isPrivate = msg.startsWith("@");
if (isPrivate) {
int idx = msg.indexOf(":");
String targetName = msg.substring(1, idx);
msg = msg.substring(idx + 1);
for (Channel other : all) {
if (other.name.equals(targetName)) {
other.send(this.name + "悄悄的对你说:" + msg);
break;
}
}
} else {
for (Channel other : all) {
if (other == this) {
continue;
}
if (!isSys) {
other.send(this.name + "对所有人说:" + msg);
} else {
other.send(msg);
}
}
}
}
private void release() {
this.isRunning = false;
Utils.close(dis, dos, client);
all.remove(this);
sendOthers(this.name + "离开了群聊...", true);
}
@Override
public void run() {
while (isRunning) {
String msg = receive();
if (!msg.equals("")) {
sendOthers(msg, false);
}
}
}
}
}
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("-----Client-----");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入用户名:");
String name = br.readLine();
Socket client = new Socket("localhost", 9999);
new Thread(new Send(client,name)).start();
new Thread(new Receive(client)).start();
}
}
public class Receive implements Runnable{
private DataInputStream dis;
private Socket client;
private boolean isRunning;
public Receive( Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
isRunning = true;
} catch (IOException e) {
System.out.println("=====2=====");
release();
}
}
private String receive() {
String msg = "";
try {
msg = dis.readUTF();
} catch (IOException e) {
System.out.println("=====4=====");
release();
}
return msg;
}
@Override
public void run() {
while(isRunning) {
String msg = receive();
if (!msg.equals("")) {
System.out.println(msg);
}
}
}
private void release() {
this.isRunning = false;
Utils.close(dis, client);
}
}
public class Send implements Runnable {
private BufferedReader console;
private DataOutputStream dos;
private Socket client;
private boolean isRunning;
private String name;
public Send(Socket client,String name) {
this.client = client;
this.name = name;
console = new BufferedReader(new InputStreamReader(System.in));
isRunning = true;
try {
dos = new DataOutputStream(client.getOutputStream());
send(name);
} catch (IOException e) {
System.out.println("=====1=====");
this.release();
}
}
@Override
public void run() {
String msg = getStrFromConsole();
if (!msg.equals("")) {
send(msg);
}
}
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
System.out.println("=====3=====");
release();
}
}
private String getStrFromConsole() {
try {
return console.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
private void release() {
this.isRunning = false;
Utils.close(dos, client);
}
}
public class Utils {
public static void close(Closeable... targets) {
for (Closeable target : targets) {
try {
if (null != target) {
target.close();
}
} catch (Exception e) {
}
}
}
}