ChatServer.java
package tungkee.javase.project;
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
private ServerSocket ss = null;
private boolean bStarted = false;
private ArrayList<Client> clients = new ArrayList<Client>();
private static int nextClientId = 0;
public static void main(String[] args) {
new ChatServer().start();
}
private void start() {
try {
ss = new ServerSocket(8888);
bStarted = true;
} catch (BindException e) {
System.out.println("端口使用中,请关闭相关程序后重试!");
System.exit(-1);
} catch (IOException e) {
e.printStackTrace();
}
try {
while(bStarted) {
Socket s = ss.accept();
Client c = new Client(s);
//将Client对象装入ArrayList中
clients.add(c);
//启动线程处理Client对象的输入输出消息
new Thread(c).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//定义一个线程专门处理与客户端的数据读写功能
private class Client implements Runnable {
private Socket s = null;
private DataInputStream dis = null;
private DataOutputStream dos = null;
private boolean bConnected = false;
private int id = 0;
public Client(Socket s) {
this.s = s;
this.id = nextClientId;
nextClientId ++;
try {
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
bConnected = true;
System.out.println("Client" + id + "与服务器成功连接。");
} catch (IOException e) {
e.printStackTrace();
}
}
private void send(String strMsg) {
try {
dos.writeUTF(strMsg);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
Client c = null;
String ReceiveMsg = null;
String strMsg = null;
while(bConnected) {
ReceiveMsg = dis.readUTF();
strMsg = "Client" + id + "(" + new Date() + ")\n";
strMsg = strMsg + " " + ReceiveMsg + "\n\n";
if(ReceiveMsg.equalsIgnoreCase("exit")) {
send("exit");
bConnected = false;
} else {
for(int i=0; i<clients.size(); i++) {
c = clients.get(i);
c.send(strMsg);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(dis != null) {
dis.close();
dis = null;
}
if(dos != null) {
dos.close();
dos = null;
}
if(s != null) {
s.close();
s = null;
}
} catch (IOException e) {
e.printStackTrace();
}
//报告客户端已经关闭
System.out.println("Client" + id + "与服务器端的连接已关闭。");
//从ArrayList中移除已经断开连接客户端引用
if(this != null) clients.remove(this);
}
}
}
}
ChatClient.java
package tungkee.javase.project;
import java.awt.*;
import java.awt.event.*;
import java.util.Date;
import java.io.*;
import java.net.*;
public class ChatClient extends Frame {
private TextField tfMessage = new TextField();
private TextArea taContent = new TextArea();
private Button btnConnect = new Button("connect");
private Button btnDisconnect = new Button("disconnect");
private Button btnClear = new Button("clear");
private Socket s = null;
private boolean bConnected = false;
private DataInputStream dis = null;
private DataOutputStream dos = null;
private Thread receive = null;
public static void main(String[] args) {
ChatClient cc = new ChatClient();
cc.launchFrame();
}
private void launchFrame() {
Panel panelUP = new Panel();
btnConnect.setEnabled(true);
btnDisconnect.setEnabled(false);
btnClear.setEnabled(true);
panelUP.setLayout(new FlowLayout(FlowLayout.LEFT));
panelUP.add(btnConnect);
panelUP.add(btnDisconnect);
panelUP.add(btnClear);
this.setLocation(300, 300);
this.setTitle("ChatClient");
this.setResizable(false);
taContent.setEditable(false);
this.add(panelUP, BorderLayout.NORTH);
this.add(taContent, BorderLayout.CENTER);
this.add(tfMessage, BorderLayout.SOUTH);
this.pack();
this.setVisible(true);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
if(s != null) disconnect();
setVisible(false);
System.exit(0);
super.windowClosing(e);
}
});
tfMessage.addActionListener(new TFListener());
btnConnect.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
connect();
}
});
btnDisconnect.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
disconnect();
}
});
btnClear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
taContent.setText("");
}
});
}
private void connect() {
try {
s = new Socket("127.0.0.1", 8888);
//打开输入管道和输出管道
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
bConnected = true;
btnConnect.setEnabled(false);
btnDisconnect.setEnabled(true);
taContent.append("System:(" + new Date() + ")连接服务器成功!\n\n");
receive = new Thread(new ReceiveThread());
receive.start();
} catch (UnknownHostException e) {
taContent.append("System:(" + new Date() + ")连接服务器失败(" + e.getMessage() + ")\n\n");
e.printStackTrace();
} catch (IOException e) {
taContent.append("System:(" + new Date() + ")连接服务器失败(" + e.getMessage() + ")\n\n");
e.printStackTrace();
}
}
private void disconnect() {
try {
sendMessage("exit");
bConnected = false;
receive.join();
btnConnect.setEnabled(true);
btnDisconnect.setEnabled(false);
taContent.append("System:(" + new Date() + ")断开服务器成功!\n\n");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//关闭输入管道和输出管道
try {
if(dis != null) {
dis.close();
dis = null;
}
if(dos != null) {
dos.flush();
dos.close();
dos = null;
}
if(s != null) {
s.close();
s = null;
}
} catch (IOException e) {
taContent.append("System:(" + new Date() + ")断开服务器失败(" + e.getMessage() + ")\n\n");
e.printStackTrace();
}
}
}
private class TFListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if(s == null) connect();
String strMsg = tfMessage.getText();
if(strMsg.equalsIgnoreCase("exit")) strMsg = "e x i t";
sendMessage(strMsg);
tfMessage.setText("");
}
}
private void sendMessage(String strMsg) {
try {
dos.writeUTF(strMsg);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private class ReceiveThread implements Runnable {
@Override
public void run() {
String strMsg = null;
try {
while(bConnected) {
strMsg = dis.readUTF();
if(! strMsg.equalsIgnoreCase("exit")) {
taContent.append(strMsg);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}