这是我09年写的第一个Java程序,一个类QQ聊天软件,当时是为了练习,现在把源码拿出来,当时水平有限,现在也没动力去优化了,希望能对Java初学者有一些帮助!说老实话,好多东西都忘了,但是仍有好多人找我,说要“交作业”和“毕业设计写论文”的,请大家先学好java基础,课本上的基础知识是有的,但是课本上却没告诉我们怎么把这些知识组合起来成为一个软件,这才是做作业、写论文的最大的价值所在,这才也是中国教育目前最大的悲哀。
实现思路:
首先每登录一个用户都会先到主持人这边登记,会记录每个用户的联系方式(这些都是只有主持人知道),然后主持人会通知已经登记的用户又有新用户加入;
李四想和张三说话,就把想说的话告诉主持人,由主持人帮你传话给张三,李四是不知道怎么才能联系到张三,但是主持人有每个用户的联系方式;
私聊是一对一聊,如果群里只有一个两个人,那这个群聊也就是私聊;
一共包含六个类:
Client.java
Clientframe.java
ClientUtil.java
Message.java
Server.java
Usermessage.java
Client.java:
import java.awt.Color;
import java.awt.FileDialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
/**
*
* @author tian QQ客户端
*/
public class Client extends Clientframe {
Message receivemsg; // 在线用户之间的聊天信息
Usermessage usermsg; // 用户信息
Socket s;
ObjectOutputStream oos;
String ipaddress; // 服务器IP
ArrayList al = new ArrayList();
String cmd;
boolean flag = false;
/**
* 构造方法
*/
public Client() {
usermsg = new Usermessage();
try {
usermsg.ip = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e3) {
e3.printStackTrace();
}
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//上线时触发,发送用户信息(usermsg)给服务器
jb1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String ipaddress = jtfname2.getText(); // 得到服务器IP
try {
if (flag == false) {
s = new Socket(ipaddress, 9999);
oos = new ObjectOutputStream(s.getOutputStream());
flag = true;
}
} catch (UnknownHostException e2) {
e2.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
}
try {
usermsg.username = jtfname.getText();
usermsg.password = jtfpwd.getText();
usermsg.flag1 = true; // 登陆是设为true
oos.writeObject(usermsg);
oos.reset();
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
ClientThread ct = new ClientThread();
ct.start();
}
});
// 监听用户下线信息
jfb.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
Usermessage usermsg1 = new Usermessage();
usermsg1.flag1 = false; // 表明用户下线
usermsg1.username = usermsg.username;
usermsg1.password = usermsg.password;
try {
usermsg1.ip = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e2) {
e2.printStackTrace();
}
// 将用户信息发给服务器说明该客户要下线
try {
oos.writeObject(usermsg1);
System.exit(0);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
// 监听双击在线用户列表事件
jli.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
JList source = (JList) e.getSource();
Object[] selection = source.getSelectedValues();
cmd = (String) selection[0];
String[] ss = cmd.split("\s+");
jfaa.setTitle("与" + ss[0] + "聊天");
jfaa.setVisible(true);
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
});
//监听私聊send按钮
jbaa.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ClientUtil cu = new ClientUtil();
Message m = new Message();
m.fromname = usermsg.username;
m.msg = jtabb.getText();
String[] ss = cmd.split("\s+");
m.toname = ss[0];
m.flag = true;
try {
oos.writeObject(m);
} catch (IOException e1) {
e1.printStackTrace();
}
jtabb.setText("");
// 调用ClientUtil中的dealmessage()方法对信息进行处理
ArrayList msglist = ClientUtil.dealmessage(m.msg);
// 调用ClientUtil中的printmsg()将信息显示到面板上
cu.printmsg(msglist, jtaaa,m);
}
});
// 监听群聊send按钮
jba.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Message m = new Message();
m.fromname = usermsg.username;
m.msg = textPane1.getText();
m.toname = "alluser";
try {
oos.writeObject(m);
} catch (IOException e1) {
// e1.printStackTrace();
}
textPane1.setText("");
}
});
// 监听Transportfile按钮,实现文件传输,只能传输小文件
jbbc.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
FileDialog f = new FileDialog(jfaa, "文件传送", FileDialog.LOAD);
f.setVisible(true);
String filename = f.getDirectory() + f.getFile();
File file = new File(filename);
FileInputStream fis;
try {
fis = new FileInputStream(file);
int len = (int) file.length();
byte[] data = new byte[len];
fis.read(data);
Message m = new Message();
m.data = new byte[len];
m.fromname = usermsg.username;
String[] ss = cmd.split("\s+");
m.toname = ss[0];
m.flag = false;
for (int i = 0; i < data.length; i++) {
m.data[i] = data[i];
}
oos.writeObject(m);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
}
}
});
// 监听"群聊"按钮
jb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
jfa.setVisible(true);
}
});
}
//显示在线用户列表(由服务器传入)
class ClientThread extends Thread {
ObjectInputStream ois;
public void run() {
ClientUtil cu = new ClientUtil();
try {
ois = new ObjectInputStream(s.getInputStream());
while (true) {
Object[] o = (Object[]) ois.readObject();
// 处理“用户名重名”信息
if (o[0] instanceof String) {
String s1 = (String) o[0];
if (s1.equals("用户名重复请重新填写")) {
jtfname3.setText(s1);
} else {
jfb.setTitle(jtfname.getText());
jfb.setVisible(true);
jf.setVisible(false);
}
}
// 处理用户信息
if (o[0] instanceof Usermessage) {
Usermessage u = (Usermessage) o[0];
// 处理用户上线信息
if (u.flag1) {
dlm.clear();
for (int i = 0; i < o.length; i++) {
dlm.addElement(o[i].toString());
}
} else {
// 处理用户下线信息
for (int i = 0; i < dlm.size(); i++) {
String s = dlm.get(i).toString();
String[] ss = s.split("\s+");
if (ss[0].equals(u.username)) {
dlm.remove(i);
break;
}
}
}
}
// 处理聊天信息
if (o[0] instanceof Message) {
Message u = (Message) o[0];
// 处理群聊信息
if (u.toname.equals("alluser")) {
// 调用ClientUtil中的dealmessage()方法对信息进行处理
ArrayList msglist = ClientUtil.dealmessage(u.msg);
// 调用ClientUtil中的printmsg()将信息显示到面板上
cu.printmsg(msglist, textPane,u);
}
// 处理私聊信息
if (u.toname.equals(usermsg.username)) {
if (u.flag) {
jfaa.setVisible(true);
jfaa.setTitle("与" + u.fromname + "聊天");
// 调用ClientUtil中的dealmessage()方法对信息进行处理
ArrayList msglist = ClientUtil.dealmessage(u.msg);
// 调用ClientUtil中的printmsg()将信息显示到面板上
cu.printmsg(msglist, jtaaa,u);
cmd = u.fromname;
} else {
// 处理接收文件
FileDialog f = new FileDialog(jfaa,
"文件接收", FileDialog.SAVE);
f.setVisible(true);
String filename = f.getDirectory()
+ f.getFile();
FileOutputStream fos = new FileOutputStream(
filename);
byte[] buf = u.data;
fos.write(buf);
fos.close();
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Client c = new Client();
}
}
Clientframe.java:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import sun.awt.image.ToolkitImage;
import sun.reflect.generics.scope.Scope;
/**
*
* @author tian
*
*/
public class Clientframe {
// 登陆窗口
JFrame jf;
JPanel jp1;
JPanel jp2;
JLabel jl1;
JLabel jl2;
JLabel jl3;
JLabel jl4;
JLabel jl5;
JLabel jl6;
JLabel jl7;
Checkbox cb;
Checkbox cb2;
Choice ci ;
ImageIcon im;
JLabel jl8;
JTextField jtfname;
JPasswordField jtfpwd;
JTextField jtfname2;
JTextField jtfname3;
JButton jb1;
JButton jb2;
// 群聊窗口
JFrame jfa;
JPanel jpa;
JPanel jp;
JPanel jpl;
TextArea jtaa;
TextArea jtab;
JButton jba;
JButton jbb;
JButton jbc;
JTextPane textPane;
JTextPane textPane1;
ImageIcon iic;
// 私聊窗口
JFrame jfaa;
JPanel jpaa;
JPanel jpp;
JPanel jpll;
JTextPane jtaaa;
JTextPane jtabb;
JButton jbaa;
JButton jbbb;
JButton jbbc;
ImageIcon iic2;
// 上线用户列表
JFrame jfb;
JPanel jpan;
JPanel jpan1;
DefaultListModel dlm;
JList jli;
JButton jb;
ImageIcon ii;
ImageIcon iii;
JLabel jl;
// 群聊表情窗口
JFrame jfc;
JPanel jpbq;
/**
*
*/
public Clientframe(){
// 初始化群聊表情窗口
jfc = new JFrame("表情");
jpbq = new JPanel();
jfc.add(jpbq, BorderLayout.CENTER);
jpbq.setLayout(new GridLayout(5,5));
jfc.add(jpbq);
URL qqurl = this.getClass().getClassLoader().getResource("Image/qq.jpg");
jfc.setIconImage(Toolkit.getDefaultToolkit().createImage(qqurl));
ArrayList al = new ArrayList();
for (int i = 10; i < 35; i++) {
URL url = this.getClass().getClassLoader().getResource( "Image/"+i+".gif");
ImageIcon ii=new ImageIcon(url);
JLabel jl = new JLabel(ii);
al.add(jl);
}
for (int j = 0; j < al.size(); j++) { JLabel jl = (JLabel) al.get(j); jl.addMouseListener(new MouseListener(){ public void mouseClicked(MouseEvent e) { StyledDocument doc = textPane1.getStyledDocument(); SimpleAttributeSet attr = new SimpleAttributeSet(); StyleConstants.setForeground(attr, Color.red); String s = e.getSource().toString(); Pattern p = Pattern.compile(".gif"); Matcher m = p.matcher(s); while(m.find()){ int start = m.start(); int end = m.end(); String subs = s.substring(start-2,end); String path = "d:\"+subs; textPane1.setCaretPosition(doc.getLength()); // 设置插入位置 File file = new File(path); Icon image = new ImageIcon(file.getAbsoluteFile().toString()); textPane1.insertIcon(image); try { doc.insertString(doc.getLength(), file.getName(), attr); } catch (BadLocationException e1) { e1.printStackTrace(); } } } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } }); jpbq.add(jl); } jfc.setVisible(false); jfc.setSize(250,250); // 初始化登陆窗口 jf = new JFrame("QQ用户登陆"); jp1 = new JPanel(); jp2 = new JPanel(); jtfname = new JTextField("",15); jtfpwd = new JPasswordField("",15); jtfname2 = new JTextField("",15); jl1 = new JLabel("QQ账号:"); jl2 = new JLabel("QQ密码:"); jl3 = new JLabel("ServerIP:"); jl4 = new JLabel("申请账号"); jl5 = new JLabel("忘了密码"); jl6 = new JLabel("QQ状态:"); jl7=new JLabel("动感地带 "); cb = new Checkbox("自动登录"); cb2 = new Checkbox("记住密码"); ci = new Choice(); jb1 = new JButton("登录"); jb2 = new JButton("退出"); URL jmurl =this.getClass().getClassLoader().getResource("Image/jm.jpg"); im = new ImageIcon(jmurl); jl8=new JLabel(im); jf.add(jp1,BorderLayout.CENTER); jf.add(jp2,BorderLayout.SOUTH); jp1.add(jl8); jp1.add(jl1); jp1.add(jtfname); jp1.add(jl4); jp1.add(jl2); jp1.add(jtfpwd); jp1.add(jl5); jp1.add(jl3); jp1.add(jtfname2); jp1.add(jl7); jp1.add(jl6); jp1.add(ci); jp1.add(cb2); jp1.add(cb); jp2.add(jb1); jp2.add(jb2); jf.setBackground(new Color(100, 253, 98)); jp1.setBackground(new Color(176, 224, 230 )); jp2.setBackground(new Color(127, 255, 212 )); ci.add("在线"); ci.add("Q我吧"); ci.add("忙碌"); ci.add("离开"); ci.add("静音"); ci.add("隐身"); jl1.setForeground(Color.BLUE); jl2.setForeground(Color.BLUE); jl3.setForeground(Color.BLUE); jl4.setForeground(Color.BLUE); jl5.setForeground(Color.BLUE); jl7.setForeground(Color.BLUE); jb1.setSize(20, 10); jb2.setSize(20, 10); jf.setSize(333, 250); jf.setIconImage(Toolkit.getDefaultToolkit().createImage(qqurl)); jf.setLocation(500, 250); jf.setResizable(false); jf.setVisible(true); jb2.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { System.exit(1); } }); // 初始化群聊窗口 jfa = new JFrame("QQ聊天室"); jpa = new JPanel(); jp = new JPanel(); jpl = new JPanel(); dlm = new DefaultListModel(); URL iicurl =this.getClass().getClassLoader().getResource("Image/12.gif"); iic=new ImageIcon(iicurl); textPane = new JTextPane(); textPane1 = new JTextPane(); textPane.setPreferredSize(new Dimension(360, 200)); textPane1.setPreferredSize(new Dimension(360, 100)); textPane.setFont(new Font("Serif",Font.BOLD,14)); textPane1.setFont(new Font("Serif",Font.BOLD,14)); JScrollPane scrollPane = new JScrollPane(textPane); JScrollPane scrollPane1 = new JScrollPane(textPane1); textPane1.setForeground(Color.red); jba = new JButton("发送"); jbb = new JButton("清空"); jbc = new JButton("表情",iic); jbc.setMnemonic(KeyEvent.VK_F);//给“表情”按钮设置快捷键 jba.setForeground(Color.BLUE); jbb.setForeground(Color.BLUE); jbc.setForeground(Color.BLUE); jfa.add(jpa, BorderLayout.NORTH); jfa.add(jp, BorderLayout.CENTER); jfa.add(jpl, BorderLayout.SOUTH); jfa.setIconImage(Toolkit.getDefaultToolkit().createImage(qqurl)); jpa.add(scrollPane); jp.add(scrollPane1); jpl.add(jba); jpl.add(jbc); jpl.add(jbb); jpa.setBackground(new Color(100, 253, 98)); jp.setBackground(new Color(100, 253, 98)); jpl.setBackground(new Color(100, 253, 98)); jfa.setSize(380, 400); jfa.setLocation(500, 150); jfa.setResizable(false); jfa.setVisible(false); jbb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { textPane1.setText(""); } }); // 监听群聊表情按钮 jbc.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { jfc.setVisible(true); jfc.setLocation(500, 150); } }); // 初始化私聊窗口 jfaa = new JFrame("私聊"); jpaa = new JPanel(); jpp = new JPanel(); jpll =new JPanel(); URL transcurl =this.getClass().getClassLoader().getResource("Image/trans.gif"); iic2 =new ImageIcon(transcurl); jtaaa = new JTextPane(); jtabb = new JTextPane(); jtaaa.setPreferredSize(new Dimension(360, 200)); jtabb.setPreferredSize(new Dimension(360, 100)); JScrollPane scrollPanea = new JScrollPane(jtaaa); JScrollPane scrollPaneb = new JScrollPane(jtabb); jtabb.setForeground(Color.red); jbaa = new JButton("发送"); jbbb = new JButton("清空"); jbbc = new JButton("",iic2); jbc.setMnemonic(KeyEvent.VK_F); jtaaa.setFont(new Font("Serif",Font.BOLD,14)); jtabb.setFont(new Font("Serif",Font.BOLD,14)); jbaa.setForeground(Color.BLACK); jbbb.setForeground(Color.BLACK); jbbc.setForeground(Color.BLACK); jfaa.add(jpaa,BorderLayout.NORTH); jfaa.add(jpp,BorderLayout.CENTER); jfaa.add(jpll,BorderLayout.SOUTH); jfaa.setIconImage(Toolkit.getDefaultToolkit().createImage(qqurl)); jpaa.add(scrollPanea); jpp.add(scrollPaneb); jpll.add(jbaa); jpll.add(jbbc); jpll.add(jbbb); jf.setBackground(new Color(100, 253, 98)); jpaa.setBackground(new Color(100, 253, 98)); jpp.setBackground(new Color(100, 253, 98)); jpll.setBackground(new Color(100, 253, 98)); jfaa.setSize(380, 400); jfaa.setLocation(500, 150); jfaa.setResizable(false); jfaa.setVisible(false); jbbb.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { jtabb.setText(""); } }); // 初始化上线用户列表 jfb = new JFrame(); jpan = new JPanel(); dlm = new DefaultListModel(); jli = new JList(dlm); jb = new JButton(">>>群聊模式");
jli.setForeground(Color.BLUE);
jb.setSize(15, 20);
jb.setForeground(Color.BLUE);
jfb.add(jpan);
jpan.setLayout(new BorderLayout());
jpan.add(jli, BorderLayout.CENTER);
jpan.add(jb, BorderLayout.SOUTH);
jpan.add(jli);
jfb.setIconImage(Toolkit.getDefaultToolkit().createImage(qqurl));
jfb.setResizable(false);
jfb.setLocation(500, 200);
jfb.setSize(200, 450);
jfb.setVisible(false);
}
}
ClientUtil.java:
import java.awt.Color;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class ClientUtil {
/**
* 处理已接收信息,将表情与字符分开
*/
public static ArrayList dealmessage(String message) {
String msg = message;
// 处理字符串
ArrayList list = new ArrayList();
ArrayList substrlist = new ArrayList();
list.add(0);
Pattern p = Pattern.compile(".gif");
Matcher m = p.matcher(msg);
while (m.find()) {
int start = m.start() - 2;
list.add(start);
start = start + 6;
if (start > msg.length()) {
break;
}
list.add(start);
}
for (int i = 0; i < list.size(); i++) {
if (i < list.size()-1) {
int begin = Integer.parseInt(list.get(i).toString());
int over = Integer.parseInt(list.get(i + 1).toString());
String subs = msg.substring(begin, over);
substrlist.add(subs);
}else{
String subs = msg.substring(Integer.parseInt(list.get(i).toString()));
substrlist.add(subs);
}
}
return substrlist;
}
/**
* 将处理过的信息显示在聊天面板上
*/
public void printmsg(ArrayList list,JTextPane tPane,Message u){
Icon image = null;
JTextPane textPane = tPane;
StyledDocument doc = textPane.getStyledDocument();
SimpleAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setForeground(attr, Color.red);
ArrayList msglist = list;
Pattern p = Pattern.compile(".gif");
try {
doc.insertString(doc.getLength(), u.toString() ,
attr);
} catch (BadLocationException e1) {
e1.printStackTrace();
}
for (int i = 0; i < msglist.size(); i++) {
String sub = msglist.get(i).toString();
Matcher m = p.matcher(sub);
if(m.find()){
URL url = this.getClass().getClassLoader().getResource("Image/" + sub);
textPane.setCaretPosition(doc.getLength()); // 设置插入位置
image = new ImageIcon(url);
textPane.insertIcon(image);
}else{
try {
doc.insertString(doc.getLength(), sub ,
attr);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}
try {
doc.insertString(doc.getLength(), "n" ,
attr);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}
Message.java:
import java.io.Serializable;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
/**
*
* @author tian
* 在线用户之间的聊天信息
*/
public class Message implements Serializable{
public String fromname;
public String toname;
public String msg;
public boolean flag;
byte[] data = null;//用于传送文件
int len; //信息会随着文件的长度而变化
public Message(){
}
public int getLen() {
return len;
}
public void setLen(int len) {
this.len = len;
}
public String toString() {
Date today = new Date();
Locale cnLocale = new Locale("zh", "CN");
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, cnLocale);
return fromname+" 于"+df.format(today)+"说:"+"n";
}
}
Server.java:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
/**
*
* @author tian QQ服务器端
*
*/
public class Server {
JFrame jf = new JFrame("QQ服务器");
JPanel jp = new JPanel();
JPanel jp1 = new JPanel();
JTextArea jta = new JTextArea();
JTextArea jta1 = new JTextArea();
JScrollPane jsp = new JScrollPane(jta1);
JLabel jl = new JLabel("QQ在线列表");
protected ServerSocket ss;
DefaultListModel dlm = new DefaultListModel();
JList jli = new JList(dlm);
ArrayList uml = new ArrayList();
HashMap mp = new HashMap(); //存储socket对应的oos
HashMap mp1 = new HashMap(); //存储用户所对应的socket
// 初始化服务器
public Server() {
jf.add(jp, BorderLayout.NORTH);
jp.setLayout(new FlowLayout(FlowLayout.LEFT));
jp.add(jl);
jf.add(jli, BorderLayout.CENTER);
jf.add(jsp, BorderLayout.SOUTH);
jta1.setSize(250, 300);
jsp.setSize(250, 300);
jf.setSize(250, 500);
jf.setLocation(500, 150);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
try {
ss = new ServerSocket(9999);
Thread t = new ServerThread();
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* 监听线程
*
*/
class ServerThread extends Thread {
public void run() {
try {
while (true) {
Socket sc = ss.accept();
ObjectOutputStream oos = new ObjectOutputStream(sc
.getOutputStream());
mp.put(sc, oos);
SocketThread st = new SocketThread(sc);
st.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*
* 读线程
*
*/
class SocketThread extends Thread {
Socket sc;
public SocketThread(Socket sc) {
this.sc = sc;
}
public void run() {
try {
ObjectInputStream ois = new ObjectInputStream(sc
.getInputStream());
while (true) {
Object m = ois.readObject();
// 处理用户信息
if (m instanceof Usermessage) {
Usermessage u = (Usermessage) m;
// 如果flag1为true,则是登陆信息
if (u.flag1 && Server.checkuser(u,uml,mp)) {
mp1.put(u.username, sc);
dlm.addElement(sc.getRemoteSocketAddress() + "n");
uml.add(u);
Object[] o = uml.toArray();
Iterator i = mp.keySet().iterator();
while (i.hasNext()) {
Socket sc = (Socket) i.next();
((ObjectOutputStream) mp.get(sc))
.writeObject(o);
}
} else if(!u.flag1){
ois.close();
ObjectOutputStream oos = (ObjectOutputStream) mp
.get(sc);
oos.close();
sc.close();
mp.remove(sc);
for (int i = 0; i < uml.size(); i++) { // 通过for循环可以遍历ArrayList
Usermessage um = (Usermessage) uml.get(i); // 通过下标输出ArrayList里面的值
if (um.username.equals(u.username)) {
uml.remove(i);
break;
}
}
Object[] o = new Object[1];
o[0] = u;
Iterator i = mp.keySet().iterator();
while (i.hasNext()) {
Socket sc = (Socket) i.next();
((ObjectOutputStream) mp.get(sc))
.writeObject(o);
}
}
}
// 处理聊天信息
if (m instanceof Message) {
Message u = (Message) m;
//处理群聊
if (u.toname.equals("alluser")) {
ArrayList al = new ArrayList();
al.add(u);
Object[] o1 = al.toArray();
Iterator i = mp.keySet().iterator();
while (i.hasNext()) {
Socket sc = (Socket) i.next();
((ObjectOutputStream) mp.get(sc))
.writeObject(o1);
}
}else{
//处理私聊和文件传送
ArrayList al = new ArrayList();
al.add(u);
Object[] o1 = al.toArray();
((ObjectOutputStream) mp.get(mp1.get(u.toname))).writeObject(o1);
}
}
}
} catch (IOException e1) {
// e1.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
//检测用户名是否重复
public static boolean checkuser(Usermessage u,ArrayList uml,HashMap mp){
ArrayList uml1 = uml;
int i;
for (i = 0; i < uml1.size(); i++) { // 通过for循环可以遍历ArrayList Usermessage um = (Usermessage) uml1.get(i); // 通过下标输出ArrayList里面的值 if (um.username.equals(u.username)) { String s = "用户名重复请重新填写"; Object[] o = new Object[1]; o[0] = s; Iterator it = mp.keySet().iterator(); while (it.hasNext()) { try { Socket sc = (Socket) it.next(); ((ObjectOutputStream) mp.get(sc)) .writeObject(o); } catch (IOException e) { e.printStackTrace(); } } break; } } if(i>=uml1.size()){
String s = "success";
Object[] o = new Object[1];
o[0] = s;
Iterator it = mp.keySet().iterator();
while (it.hasNext()) {
try {
Socket sc = (Socket) it.next();
((ObjectOutputStream) mp.get(sc))
.writeObject(o);
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}else{
return false;
}
}
public static void main(String[] args) {
Server s = new Server();
}
}
Usermessage.java:
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* @author tian
* 用于传递用户信息
*/
public class Usermessage implements Serializable{
public String username; //用户名称
public String password; //用户密码
public String ip; //用户IP
public boolean flag1; //标志用户上线还是下线,为true表示为登陆
public String ipaddress; //服务器IP
public Usermessage(){
}
public boolean equals(Usermessage user) {
boolean flag= false;
if(ip.equals(user.ip)){
flag = true;
}
return flag;
}
public String toString() {
return username + " "+ ip;
}
}
打包好的程序和图片资源下载地址:
http://download.csdn.net/detail/xionglong/1638561
效果: