Java编写的类QQ聊天系统
这是我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
效果: