我是边看马士兵Java视频的聊天室项目边自己动手写的。
具体的思路为:
0.1版本:首先创建一个窗口,然后添加对右上角关闭按钮的事件反应。添加一个TextArea和一个TextField。
0.2版本:对输入框的回车事件进行监听和处理(在显示框显示,将输入框清空)。
0.3版本:编写服务器端,考虑到多客户端的情况,进行多线程处理。主线程只负责接收连接。其他操作(此版本只验证是否连接上)由新线程处理。
0.4版本:客户端添加连接和关闭连接的方法,主要是资源的初始化和回收。还有将输入框的事件反应改为发送到服务器端。
0.5版本:服务器端接收方法,群发方法。
0.6版本:客户端的接收方法,将接收到的内容显示在显示框。
0.7版本:考虑各种突发情况和错误,对程序进行调试,对各种Exception进行不同处理,增强程序的健壮性。
至此版本源代码如下:
客户端ChatClient.java
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
public class ChatClient {
//主线程
public static void main(String[] args){
new ChatFrame("ChatRoom").launchFrame();
}
}
class ChatFrame extends Frame
{
TextField inputField = new TextField();
TextArea outputArea = new TextArea();
Socket socket = null;
DataOutputStream chatInput = null;
DataInputStream chatRecieve = null;
//构造方法
public ChatFrame(String s){
super(s);
}
//窗口
public void launchFrame(){
setLocation(400,400);
setSize(300,300);
add(inputField,BorderLayout.SOUTH);
add(outputArea,BorderLayout.NORTH);
//X
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e){
disconnect();
System.exit(0);
}
});
inputField.addActionListener(new ChatInputListener());
pack();
setVisible(true);
connect();
//new Thread(new Recieve()).start();
recieve();
}
public void connect(){
try{
socket = new Socket("127.0.0.1",5000);
chatInput = new DataOutputStream(socket.getOutputStream());
chatRecieve = new DataInputStream(socket.getInputStream());
//test
System.out.println("connect");
} catch (Exception e){
e.printStackTrace();
}
}
public void disconnect(){
try{
chatInput.writeUTF("#exit");
if(chatInput != null) chatInput.close();
if(chatRecieve != null) chatRecieve.close();
if(socket != null) socket.close();
}catch (IOException e){
e.printStackTrace();
}
}
//class Recieve implements Runnable
//{
//public void run(){
public void recieve(){
while(true){
try{
String s = chatRecieve.readUTF();
String s2 = outputArea.getText();
outputArea.setText(s2 + s);
} catch (IOException e) {
//e.printStackTrace();
}
}
}
//}
class ChatInputListener implements ActionListener
{
public void actionPerformed(ActionEvent e){
String s1 = inputField.getText();
s1 = s1 + "\n";
try{
chatInput.writeUTF(s1);
} catch (IOException ioe) {
ioe.printStackTrace();
}
inputField.setText("");
}
}
}
服务器端ChatServer.java
import java.net.*;
import java.io.*;
import java.util.*;
public class ChatServer
{
public static void main(String[] args){
new Server().start();
}
}
class Server
{
private ServerSocket server = null;
private Socket socket = null;
private int clientid = 0;
private ArrayList
public void start(){
try{
server = new ServerSocket(5000);
//测试
System.out.println("server has started.");
} catch(IOException e) {
e.printStackTrace();
}
try{
while(true){
socket = server.accept();
clientid++;
Client client = new Client(socket,clientid);
clients.add(client);
new Thread(client).start();
//测试
System.out.println("client " + clientid + " has connected.");
}
} catch(IOException e) {
e.printStackTrace();
}
}
public void send(String s){
for(int i = 0; i
try{
c.chatSend.writeUTF(s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Client implements Runnable
{
int id = 0;
Socket socket = null;
DataInputStream chatInput = null;
DataOutputStream chatSend = null;
public Client(Socket socket,int id){
this.id = id;
this.socket = socket;
try{
chatInput = new DataInputStream(socket.getInputStream());
chatSend = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
while(!socket.isClosed()){
try{
String s = chatInput.readUTF();
if(s.equals("#exit")) {
System.out.print("client " + id + "已退出 \n");
send("client " + id + "已退出 \n");
chatInput.close();
socket.close();
clients.remove(this);
} else {
//System.out.print("client " + id + ":" + s);
send("client " + id + ":" + s);
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
}