1.server
package www10m23chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class ChatServer {
// 保留每一个聊天客户对应的Socket对象
private Set<Socket> clients;
private List<String> list;
public void init() {
list=new ArrayList<String>();
clients = new HashSet();
try {
ServerSocket ss = new ServerSocket(9856);
System.out.println("Chat Server started.");
while (true) {
Socket socket = ss.accept();
clients.add(socket);
//从客户端socket.getInputStream中获取输入流
BufferedReader br=new BufferedReader(
new InputStreamReader(socket.getInputStream()));
//读取 username
String username=br.readLine();
System.out.println(username);
list.add(username);
String str="";
for (int i = 0; i < list.size(); i++) {
str+=list.get(i)+",";
}
str=str.substring(0, str.length()-1);
for (Socket s : clients) {
PrintWriter pw=new PrintWriter(s.getOutputStream());
pw.println("login#"+str);
pw.flush();
}
System.out.println(socket.getInetAddress());
ChatServerThread cst = new ChatServerThread(socket, clients,list);
cst.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new ChatServer().init();
}
}
class ChatServerThread extends Thread {
private Socket socket;
private Set<Socket> clients;// 所有聊天用户socket对象的集合
private List<String> list;
public ChatServerThread(Socket s, Set clients,List<String> list) {
this.socket = s;
this.clients = clients;
this.list=list;
}
// 反复接受这个客户发过来的聊天内容
// 接受到聊天内容后,把这个聊天内容广播给所有的聊天用户
// 这个用户退出了,不用接受这个用户的输入,这个线程结束
// 从用户Socket的集合中,移除当前Socket对象
public void run() {
try {
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while (true) {
String s = br.readLine();
if (s.indexOf("#exit") != -1) {
String[] arr = s.split("#");
clients.remove(socket);
is.close();
socket.close();
String ss=arr[2] + ",exit";
System.out.println(ss);
// BASE64Encoder en=new BASE64Encoder();
// ss=en.encode(ss.getBytes());
broadcast(ss, clients);
list.remove(arr[2]);
String str="";
for (int i = 0; i < list.size(); i++) {
str+=list.get(i)+",";
}
if(str.length()!=0){
str=str.substring(0, str.length()-1);
list.remove(arr[2]);
for (Socket c : clients) {
PrintWriter pw=new PrintWriter(c.getOutputStream());
pw.println("exit#"+str);
pw.flush();
}
}
break;
}
broadcast(s, clients);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 把当前用户输入聊天内容,广播给所有的聊天用户
private void broadcast(String str, Set clients) {
// for (Socket s : clients) {
Iterator it=clients.iterator();
while(it.hasNext()){
Socket s=(Socket) it.next();
try {
PrintWriter pw = new PrintWriter(s.getOutputStream());
pw.println(str);
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.client
package www10m23chat;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JOptionPane;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class ChatClient implements ActionListener {
private JFrame jf;
private String serverIp;
private String username;
private Socket socket;
private JTextField jtf;
private PrintWriter pw;
private int port = 9856;
private JTextArea jta;
private RefreshMessageThread rmt;
private JList userList;
public void init() {
userList=new JList();
userList.setFont(new Font("宋体", Font.BOLD, 20));
jf = new JFrame("聊天客户端 v1.0");
// serverIp = JOptionPane.showInputDialog(jf, "请输入聊天服务器的地址");
// serverIp="172.16.1.10";
serverIp = "127.0.0.1";
username = JOptionPane.showInputDialog(jf, "请输入聊天昵称");
jta = new JTextArea(20, 50);
jta.setEditable(false);
Font font = new Font("宋体", Font.BOLD, 24);
jta.setFont(font);
jta.setText("欢迎" + username + "使用我们的聊天程序,祝您聊的愉快!\n");
JScrollPane jsp = new JScrollPane(jta);
jf.add(jsp, BorderLayout.CENTER);
JPanel jp = new JPanel();
JLabel ja = new JLabel(username + "说:");
jtf = new JTextField(50);
JButton jb = new JButton("提交");
jb.addActionListener(this);
jp.add(ja);
jp.add(jtf);
jp.add(jb);
JButton jb2=new JButton("抖动");
jb2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
PrintWriter pw;
try {
pw = new PrintWriter(socket.getOutputStream());
pw.println("doudong");
pw.flush();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
jp.add(jb2);
jf.add(jp, BorderLayout.SOUTH);
jtf.addActionListener(this);
jf.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// 当关闭聊天窗口,弹出退出的确认框
int i = JOptionPane.showConfirmDialog(jf, "真退出吗?");
// 当前的聊天用户真的退出
if (i == JOptionPane.YES_OPTION) {
// #exit#username
pw.println("#exit#" + username);
pw.flush();
rmt.setStop(true);
try {
Thread.sleep(200);
} catch (InterruptedException e2) {
e2.printStackTrace();
}
pw.close();
try {
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
System.exit(1);
}
}
});
JScrollPane js=new JScrollPane(userList);
jf.add(js,BorderLayout.EAST);
jf.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
// 用户按下提交按钮,执行这个方法
public void actionPerformed(ActionEvent e) {
String message = jtf.getText();
// 判断输入聊天是否为空,弹出警告框
if (message.equals("")) {
JOptionPane.showMessageDialog(jf, "请先输入聊天内容");
return;
}
if (message.equals("doudong")) {
pw.println(message);
pw.flush();
jtf.setText("");
return;
}
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm:ss");
// 聊天内容不为空,把该内容发送给服务器
message = username + "说:" + message + "\t[" + sdf.format(new Date())
+ "]";
// try {
// BASE64Encoder en = new BASE64Encoder();
// message = en.encode(message.getBytes("GBK"));
//
// } catch (UnsupportedEncodingException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// }
pw.println(message);
pw.flush();
jtf.setText("");
}
// 用来建立与聊天服务器的网络连接
public void connect() {
try {
socket = new Socket(serverIp, port);
pw = new PrintWriter(socket.getOutputStream());
pw.println(username);
pw.flush();
BufferedReader br=new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String message=br.readLine();
System.out.println(message.split("#")[1]);
String sss=message.split("#")[1];
userList.setListData(sss.split(","));
rmt = new RefreshMessageThread(jta, socket,userList);
rmt.start();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ChatClient cc = new ChatClient();
cc.init();
cc.connect();
}
}
// 用来实时接收服务器广播的聊天内容
class RefreshMessageThread extends Thread {
private JTextArea jta;
private Socket socket;
private boolean stop = false;
private JList userList;
public RefreshMessageThread(JTextArea jta, Socket socket,JList userList) {
this.jta = jta;
this.socket = socket;
this.userList=userList;
}
public void setStop(boolean stop) {
this.stop = stop;
}
public void run() {
try {
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while (!stop) {
Thread.sleep(100);
// 服务器没有广播内容,这个地方一直等待
// 得到广播的内容,追加到文本域上显示
String message = br.readLine();
if (message != null) {
System.out.println(message+"-------------");
if(message.startsWith("login#")||message.startsWith("exit#")){
System.out.println(message.split("#")[1]);
String sss=message.split("#")[1];
System.out.println(sss+"++++sssssssssssssssssssss");
userList.setListData(sss.split(","));
continue;
}
if ("doudong".equals(message)) {
JFrame jf=(JFrame) JOptionPane.getFrameForComponent(jta);
// ((JFrame) (jta.getTopLevelAncestor()))
// .setAlwaysOnTop(true);
jf.setExtendedState(JFrame.NORMAL);
jf.setAlwaysOnTop(true);
int x = jf.getX();
int y = jf.getY();
for (int i = 0; i < 20; i++) {
if ((i & 1) == 0) {
x += 3;
y += 3;
} else {
x -= 3;
y -= 3;
}
jf.setLocation(x, y);
//
try {
Thread.sleep(50);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
((JFrame) (jta.getTopLevelAncestor()))
.setAlwaysOnTop(false);
}
continue;
}
// BASE64Decoder de = new BASE64Decoder();
// message = new String(de.decodeBuffer(message), "GBK");
System.out.println(message);
jta.append("\n" + message);
jta.select(jta.getText().length(), jta.getText().length());
}
}
br.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}