客戶端 ChatClient.java:
package com.chat.client;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 聊天程序客戶端
* @author Tandaly
* @date 2013-6-17 上午9:01:38
*/
public class ChatClient extends Frame
{
private static final long serialVersionUID = -4776932994542738425L;
private Socket socket = null;
private DataOutputStream dos = null;
private DataInputStream dis = null;
private boolean bConnected = false;//是否連接上服務器 默認爲否
private Thread connThread = new Thread(new ConnectThread());
private TextField tfTxt = new TextField();//發送文本
private TextArea taContent = new TextArea();//消息內容
/**
* 連接服務
*/
public void connect()
{
try
{
this.socket = new Socket("127.0.0.1", 9999);
this.bConnected = true;//連接服務器成功
this.dos = new DataOutputStream(this.socket.getOutputStream());
this.dis = new DataInputStream(this.socket.getInputStream());
} catch (UnknownHostException e)
{
System.out.println("SYSTEM:服務器地址有誤!");
} catch (IOException e)
{
System.out.println("SYSTEM:連接服務器失敗!");
}
}
/**
* 關閉連接
*/
public void disConnect()
{
try
{
this.bConnected = false;//斷開服務器連接
if(null != this.dos)
this.dos.close();
if(null != this.dis)
this.dis.close();
if(null != this.socket)
this.socket.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
/**
* 運行窗體
*/
public void launchFrame()
{
setLocation(500, 100);//設置窗體位置
setSize(400, 500);//設置窗體大小
//添加窗體元素
this.add(tfTxt, BorderLayout.SOUTH);//添加發送文本
this.add(taContent, BorderLayout.NORTH);//添加消息內容
pack();//去除空白
//添加一個窗口監聽事件實現窗口關閉
this.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
System.exit(0);//退出程序
}
});
tfTxt.addActionListener(new tfTxtListener());//添加發送文本回車監聽
setVisible(true);//設置窗體可見
//connect();//連接服務器操作
connThread.start();
new Thread(new ReceiveMsgThread()).start();//啓動接收消息線程
}
/**
* 入口函數
* @param args
*/
public static void main(String[] args)
{
new ChatClient().launchFrame();
}
/**
* 發送文本監聽類
* @author Tandaly
* @date 2013-6-17 上午9:05:28
*/
class tfTxtListener implements ActionListener
{
@Override
public void actionPerformed(ActionEvent e)
{
String content = taContent.getText();
String txt = tfTxt.getText().trim();
if(bConnected)
{
if(!"".equals(txt))
{
taContent.setText(content + "\n我 "
+new SimpleDateFormat("hh:MM:ss").format(new Date())+"\n " + txt);
tfTxt.setText("");
try
{
dos.writeUTF(txt);//向服務端發送消息
} catch (IOException e1)
{
System.out.println("發送消息失敗,請檢查是否正確連接服務器!");
bConnected = false;
}
}
} else
{
taContent.setText(content + "\n系統消息 "
+new SimpleDateFormat("hh:MM:ss").format(new Date())
+"\n----發送消息失敗,請檢查服務器是否連接正常----");
tfTxt.setText("");
}
}
}
/**
* 接受消息線程
* @author Tandaly
* @date 2013-6-17 上午10:01:55
*/
private class ReceiveMsgThread implements Runnable
{
@Override
public void run()
{
while(bConnected)
{
try
{
String receiveMsg = dis.readUTF();
String content = taContent.getText();
taContent.setText(content + "\n匿名 "
+new SimpleDateFormat("hh:MM:ss").format(new Date())+"\n " + receiveMsg);
} catch (IOException e)
{
System.out.println("SYSTEM:接收消息失敗,服務器未連接");
}
}
}
}
private class ConnectThread implements Runnable
{
@Override
public void run()
{
while(!bConnected)
{
try
{
socket = new Socket("127.0.0.1", 9999);
bConnected = true;
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
} catch (Exception e)
{
}
}
}
}
}
服務端 ChatServer.java:
package com.chat.server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* 聊天程序服務端
* @author Tandaly
* @date 2013-6-17 上午9:13:47
*/
public class ChatServer
{
private ServerSocket serverSocket = null;//服務socket對象
private List<ClientThread> clients = new ArrayList<ClientThread>();//客戶端集合
/**
* 啓動
*/
public void start()
{
try
{
this.serverSocket = new ServerSocket(9999);
System.out.println("----聊天服務器啓動成功!----");
} catch (BindException e)
{
System.out.println("SYSTEM ERROR:聊天服務啓動失敗,端口被佔用");
System.exit(0);
} catch (IOException e1)
{
System.out.println("SYSTEM ERROR:發生異常");
System.exit(0);
}
try
{
while(true)
{
Socket socket = this.serverSocket.accept();
ClientThread clientThread = new ClientThread(socket);//創建客戶端消息線程
new Thread(clientThread).start();//啓動處理客戶端消息線程
this.clients.add(clientThread);//把當前讀取到客戶端加入到客戶端集合中
}
} catch (IOException e)
{
e.printStackTrace();
}
}
/**
* 入口函數
* @param args
*/
public static void main(String[] args)
{
new ChatServer().start();
}
/**
* 處理客戶端消息線程類
* @author Tandaly
* @date 2013-6-17 上午9:37:59
*/
private class ClientThread implements Runnable
{
private Socket socket;
private DataInputStream dis;
private DataOutputStream dos;
public ClientThread(Socket socket)
{
this.socket = socket;
try
{
this.dis = new DataInputStream(this.socket.getInputStream());
this.dos = new DataOutputStream(this.socket.getOutputStream());
} catch (IOException e)
{
e.printStackTrace();
}
}
/**
* 發送消息給客戶端
* @param txt
*/
public void send(String txt)
{
try
{
this.dos.writeUTF(txt);
} catch (IOException e)
{
System.out.println("SYSTEM:發送消息失敗,客戶端可能已經下線!");
}//發送消息到客戶端
}
@Override
public void run()
{
try
{
while(true)
{
String txt = this.dis.readUTF();//讀取客戶端消息
System.out.println("消息:" + txt);
//向客戶端羣發消息
for(ClientThread client:clients)
{
if(this != client)
{
client.send(txt);
}
}
}
} catch (IOException e)
{
clients.remove(this);//移除當前客戶端
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
Thread.currentThread().interrupt();//終止當前線程
System.out.println("SYSTEM:線程" + Thread.currentThread().getName() + "被銷燬");
}
}
}
}
作者:Tandaly
出處:http://blog.csdn.net/tandaly/article/details/9110995