JavaSocket实现多人聊天室

上传人:小** 文档编号:26956377 上传时间:2021-08-15 格式:DOC 页数:33 大小:843KB
返回 下载 相关 举报
JavaSocket实现多人聊天室_第1页
第1页 / 共33页
JavaSocket实现多人聊天室_第2页
第2页 / 共33页
JavaSocket实现多人聊天室_第3页
第3页 / 共33页
点击查看更多>>
资源描述
Java Socket实现多人聊天室-swing做UI标签: socket 聊天 javaexception 服务器 string 2011-08-31 15:06 20679 人阅读 评论(25)收藏 举报三分类:java ( 21)-|版权声明:本文为博主原创文章,未经博主允许不得转载。今天翻硬盘的 workspace发现一个Java Socket实现多人聊天室的源码,不记得是什么时候的事情了,貌似不是我写的。但写得还不错,至少算个有模有样的聊天室工具。我简单的修改了一下,拿出来跟大家分享一下,仅供参考OOO界面是用swing写的,还不懒,简约大方。有图有真相:正如上图所示,这个程序分为 服务器端和客户端,说白了就是 两个main class,用eclipse直接运行之。聊天室的设计思想是:在局域网下,利用socket进行连接通信,当服务器端启动的时候,利用Thread线程不停的等待客户端的链接;当有客户端开启连 接的时候,服务器端通过 10流反馈 上线用户”信息给客户端,客户端也使用线程不停的接 收服务器的信息,从而实现多人在线聊天功能。程序中有三个类,分别 Server.java (服务器端)、Client (客户端)、User.java ( javabean)。代码如下:Server.java(服务器端):htmlview pla in copy1. import java.awt.BorderLayout;2. import java.awt.Color;3. import java.awt.GridLayout;4. import java.awt.Toolkit;5. import java.awt.event.ActionEvent;6. import java.awt.event.ActionListener;7. import java.awt.event.WindowAdapter;8. import java.awt.event.WindowEvent;9. import java.io.BufferedReader;10. i mport java.ioOException;11. i mport java.ionputStreamReader;12. i mport java.io.PrintWriter;13. i mport .BindException;14. i mport .ServerSocket;15. i mport .Socket;16. i mport java.util.ArrayList;17. i mport java.util.StringTokenizer;18.18. i mport javax.swing.DefaultListModel;19. i mport javax.swing.JButton;20. i mport javax.swing.JFrame;21. i mport javax.swing.JLabel;22. i mport javax.swing.JList;23. i mport javax.swing.JOptionPane;24. i mport javax.swing.JPanel;25. i mport javax.swing.JScrollPane;26. i mport javax.swing.JSplitPane;27. i mport javax.swing.JTextArea;28. i mport javax.swing.JTextField;29. i mport javax.swing.border.TitledBorder;31.30. public class Server 33.31. private JFrame frame;32. private JTextArea contentArea;33. private JTextField txt_message;34. private JTextField txt_max;35. private JTextField txt_port;36. private JButton btn_start;37. private JButton btn_stop;38. private JButton btn_send;39. private JPanel northPanel;40. private JPanel southPanel;41. private JScrollPane rightPanel;42. private JSc IPane leftPanel;43. private JSplitPane centerSplit;44. private JList userList;45. private DefaultListModel listModel;49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.75.76.77.78.79.80.81.82.83.84.85.86.87.88.private ServerSocket serverSocket;private ServerThread serverThread;private ArrayList clients;private booleanisStart=false服务器还未启没有用户在线消息不能为空!/ 主方法,程序执行入口public static void main(String args) new Server();/执行消息发送public void send() if (!isStart) JOptionPane.showMessageDialog(frame,动,不能发送消息!,”错误,JOptionPane.ERROR_MESSAGE);return;if (clients.size() = 0) JOptionPane.showMessageDialog(frame,不能发送消息!,错误,JOptionPane.ERROR_MESSAGE);return;Stringmessage = txt_message .getText().trim();if (message = null | message.equals() JOptionPane.showMessageDialog(frame,错误,JOptionPane.ERROR_MESSAGE);return;sendServerMessage(message);/群发服务器消息contentArea.append(服务器说:+ txt_message.getText() + rn);txt_message.setText(null);/构造放法public Server() frame = new JFrame( 服务器);/更改JFrame的图标:frame.setlconlmage(Toolkit.getDefaultToolkit().createlmage(Client.class.getResource(qq.png);89.frame.setlconlmage(Toolkit.getDefaultToolkit().createlmage(Server.class.getResource(qq.png);90.contentArea = new JTextArea();91.contentArea.setEditable(false);92.contentArea.setForeground(Color.blue);93.txt_message = new JTextField();94.txt_max = new JTextField(30);95.txt_port = new JTextField(6666);96.btn_start= new JButton(”启动);97.btn_stop = new JButton(” 停止);98.btn_send = new JButton(” 发送);99.btn_stop.setEnabled(false);100.listModel = new DefaultListModel();101.userList = new JList(listModel);102.103.southPanel = new JPanel(new BorderLayout();104.southPanel.setBorder(new TitledBorder(”写消息);105.southPanel.add(txt_message, Center);106.southPanel.add(btn_send, East);107.leftPanel= new JScrollPane(userList);108.leftPanel.setBorder(new TitledBorder(在线用户);109.110.rightPanel= new JScrollPane(contentArea);111.rightPanel.setBorder(new TitledBorder(消息显示区);112.113.centerSplit= new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel,114.rightPanel);115.centerSplit.setDividerLocation(100);116.northPanel = new JPanel();117.northPanel.setLayout(new GridLayout(1,6);118.northPanel.add(new JLabel(人数上限);119.northPanel.add(txt_max);120.northPanel.add(new JLabel(端口 );121.northPanel.add(txt_port);122.northPanel.add(btn_start);123.northPanel.add(btn_stop);124.northPanel.setBorder(new TitledBorder(配置信息);125.126.frame.setLayout(new BorderLayout();127.frame.add(northPanel, North);128.129.130.131.132.133.134.135.136.137.138.139.140.141.142.143.144.145.146.147.148.149.150.151.152.153.154.155.156.157.158.159.160.161.162.frame.add(centerSplit, Center);frame.add(southPanel, South);frame.setSize(600, 400);/frame.setSize (Toolkit.getDefaultToolkit().getScreenSize();设置全屏intscreen_width = Toolkit .getDefaultToolkit().getScreenSize().width;intscreen_height = Toolkit .getDefaultToolkit().getScreenSize().height;frame.setLocation(screen_width - frame.getWidth()/ 2,(screen_height - frame.getHeight() / 2);frame.setVisible(true);/关闭窗口时事件frame.addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent e) if (isStart) closeServer();/关闭服务器System.exit(O);/退岀程序);/文本框按回车键时事件txt_message.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e) send(););/单击发送按钮时事件btn_send.addActionListener(new ActionListener() public void actionPerformed(ActionEvent argO)send(););/单击启动服务器按钮时事件163.btn_start.addActionListener(new ActionListener() 164.public void actionPerformed(ActionEvent e) 165.if (isStart) 166.JOptionPane.showMessageDialog(frame,服务器已处于启动状态,不要重复启动!,167.错误, JOptionPane.ERROR_MESSAGE);168.return;169.170.int max;171.int port;172.try 173.try 174.max = Integer .parselnt(txt_max.getText();175. catch (Exception e1) 176.throw new Exception(人数上限为正整数! ”);177.178.if (max= 0) 179.throw new Exception(人数上限为正整数! ”);180.181.try 182.port = Integer .parseInt(txt_port.getText();183. catch (Exception e1) 184.throw new Exception(端口号为正整数! ”);185.186.if (port= 0) 187.throw new Exception(端口号为正整数! ”);188.189.serverStart(max, port);190.contentArea.append(服务器已成功启动!人数上限:+ max + ,端口: + port191.+ rn);192.JOptionPane.showMessageDialog(frame,服务器成功启动!);193.btn_start.setEnabled(false);194.txt_max.setEnabled(false);195.txt_port.setEnabled(false);196.197.198.199.200.201.202.203.204.205.206.207.208.209.210.211.212.213.214.215.216.217.218.219.220.221.222.223.224.225.226.227.228.229.230.231.btn_stop.setEnabled(true); catch (Exception exc) JOptionPane.showMessageDialog(frame, exc.getMessage(),错误, JOptionPane.ERROR_MESSAGE););/单击停止服务器按钮时事件btn_stop.addActionListener(new ActionListener() public void actionPerformed(ActionEvent e) if (!isStart) JOptionPane.showMessageDialog(frame,服务器还未启动,无需停止!,”错误,JOptionPane.ERROR_MESSAGE);return;try closeServer();btn_start.setEnabled(true);txt_max.setEnabled(true);txt_port.setEnabled(true);btn_stop.setEnabled(false);contentArea.append(”服务器成功停止!rn);JOptionPane.showMessageDialog(frame,服务器成功停止!); catch (Exception exc) JOptionPane.showMessageDialog(frame,停止服务器发生异常!,”错误,JOptionPane.ERROR_MESSAGE););/启动服务器public void serverStart(int max, int port) throws java.net.BindException try clientsnew ArrayList ();serverSocket = serverThread = max);serverThread.start();isStart= true catch (BindException e) isStart= falsethrow new BindException(” 个! ”); catch (Exception e1) e1.printStackTrace();isStart = false throw new BindException(”new ServerSocket(port); new ServerThread(serverSocket,端口号已被占用,请换启动服务器异常!);232.233.234.235.236.237.238.239.240.241.242.243.244.245.246.247.248.249.250.251.252.253.254.255.256.257.258.259.260.261.262.263.264.265.266.267.268.269.270./ 关闭服务器SuppressWarnings(deprecation) public void closeServer() try 停止服务器线程if (serverThread != null)serverThread.stop();/for (inti = clients .size() - 1; i=0; i-)/给所有在线用户发送关闭命令clients.get(i).getWriter().println(CLOSE);clients.get(i).getWriter().flush();/释放资源clients.get(i).stop();务的线程停止此条为客户端服clients.get(i).reader.close(); clients.get(i).writer.close(); clients.get(i).socket.close(); clients.remove(i);if (serverSocket != null) serverSocket.close();listModel.removeAIIEIements(); isStart = false ; catch (IOException e) e.printStackTrace();关闭服务器端连接清空用户列表271.272.273.274.275.276.277.278.279.280.281.282.283.284.285.286.287.288.289.290.291.292.293.294.295.296.297.298.299.300.301.302.303.304.305.trueisStart/群发服务器消息public void sendServerMessage(String message) for (inti = clients .size() - 1; i= 0; i-) clients.get(i).getWriter().println(”服务器:+ message + (多人发送);clients.get(i).getWriter().flush();/ 服务器线程class ServerThread extends Thread private ServerSocket serverSocket;private int max;/人数上限/服务器线程的构造方法public ServerThread(ServerSocket serverSocket, intmax) this.serverSocket = serverSocket ;this.max = max;public void run() while (true) /不停的等待客户端的链接try Socketsocket = serverSocket .accept();if (clients.size() = max) /女口果已达人数上限BufferedReaderr = new BufferedReader(new lnputStreamReader(socket.getlnputStream();PrintWriterw = new PrintWriter(socket.getOutputStream();/接收客户端的基本用户信息Stringinf = r .readLine();stnew StringTokStringTokenizerenizer(inf, );306.Useruser = new User(st.nextToken(),st.nextToken();307./反馈连接成功信息308.w.println(MAX服务器:对不起,+ user.getName()309.+ user.getIp() + ,服务器在线人数已达上限,请稍后尝试连接!)310.w.flush();311./释放资源312.r.close();313.w.close();314.socket.close();315.continue;316.317.ClientThreadclient=new ClientThread(socket);318.client.start();/开启对此客户端服务的线程319.clients.add(client);320.listModel.addElement(client.getUser().getName();更新在线列表321.contentArea.append(client.getUser().getName()322.+ client.getUser().getlp() + 上线!rn);323. catch (IOException e) 324.e.printStackTrace();325.326.327.328.329.330./为一个客户端服务的线程331.class ClientThread extends Thread 332.private Socket socket;333.private BufferedReader reader;334.private PrintWriter writer;335.private User user;336.337.public BufferedReader getReader() 338.return reader;339.340.341.public PrintWriter getWriter() 342.343.344.345.346.347.348.349.350.351.352.353.354.355.356.357.358.359.360.361.362.363.364.365.366.367.368.369.370.371.372.373.374.375.return writer;public User getUser() return user;/客户端线程的构造方法public ClientThread(Socket socket) try this.socket = socket ;reader = new BufferedReader(new InputStrea mReader(socket.getlnputStream();writer = new PrintWriter(socket.getOutputStream();/接收客户端的基本用户信息Stringinf = reader .readLine();StringTokenizerst = new StringTokenizer(inf, );user = new User(st.nextToken(), st.nextToken();/反馈连接成功信息writer.println(user.getName() + user.getIp()+ 与服务器连接成功 门;writer.flush();/反馈当前在线用户信息if (clients.size() 0) Stringtemp =;for (inti = clients .size() - 1; i=0; i-) temp += (clients.get(i).getUser().getName() + / + clients.get(i).getUser().getIp()+ ;writer.println(USERLIST + clients.size() + + temp);writer.flush();-)/for (int向所有在线用户发送该用户上线命令i = clients .size() - 1; i=0; i376.clients.get(i).getWriter().println(377.ADD + user.getName() + user.getip();378.clients.get(i).getWriter().flush();379.380. catch (IOException e) 381.e.printStackTrace();382.383.384.385.SuppressWarnings(deprecation)386.public void run() /不断接收客户端的消息,进行处理。387.Stringmessage = null ;388.while (true) 389.try 390.message = reader .readLine();/接收客户端消息391.if (message.equals(CLOSE)下线命令392.393.contentArea.append(this.getUser().getName()394.+ this.getUser().getIp() +下线!rn);395./断开连接释放资源396.reader.close();397.writer.close();398.socket.close();399.400./向所有在线用户发送该用户的下线命令401.for (inti = clients .size() - 1; i=0; i-)402.clients.get(i).getWriter().println(403.DELETE + user.getName();404.clients.get(i).getWriter().flush();405.406.407.listModel.removeElement(user.getName();更新在线列表442.443.408.409.410.411.412.413.414.415.416.417.418.419.420.421.422.423.424.425.426.427.428.429.430.431.432.433.434.435.436.437.438.439.440.441.=0; i-) =user) s.get(i);用户的服务线程for (intiif (clients.get(i).getUser()=ClientThreadclients.remove(i);/temp.stop();clients .size() - 1; itemp = client删除此停止这条服务线程return; else dispatcherMessage(message);/转发消息 catch (IOException e) e.printStackTrace();/转发消息new StringTopublic void dispatcherMessage(String message) kenizer(message, );Stringsource=stringTokenizer.nextToken();Stringowner =stringTokenizer.nextToken();Stringcontent=stringTokenizer.nextToken();StringTokenizerstringTokenizermessage = source + 说:+ content;contentArea.append(message + rn);if (owner.equals(ALL) /群发for (inti = clients .size() - 1; i= 0; i-)clients.get(i).getWriter().println(message + ( 多人发送);clients.get(i).getWriter().flush();Client (客户端)htmlview pla in copy1. import java.awt.BorderLayout;2. import java.awt.Color;3. import java.awt.GridLayout;4. import java.awt.Toolkit;5. import java.awt.event.ActionEvent;6. import java.awt.event.ActionListener;7. import java.awt.event.WindowAdapter;8. import java.awt.event.WindowEvent;9. import java.io.BufferedReader;10. i mport java.ioOException;11. i mport java.ionputStreamReader;12. i mport java.io.PrintWriter;13. i mport .Socket;14. i mport java.util.HashMap;15. i mport java.util.Map;16. i mport java.util.StringTokenizer;17.17. i mport javax.swing.DefaultListModel;18. i mport javax.swing.JButton;19. i mport javax.swing.JFrame;20. i mport javax.swing.JLabel;21. i mport javax.swing.JList;22. i mport javax.swing.JOptionPane;23. i mport javax.swing.JPanel;24. i mport javax.swing.JScrollPane;25. i mport javax.swing.JSplitPane;26. i mport javax.swing.JTextArea;27. i mport javax.swing.JTextField;28. i mport javax.swing.border.TitledBorder;30.29. public class Client32.30. private JFrame frame;31. private JList userList;32. private JTextArea textArea;36.private JTextField textField;37.private JTextField txt_port;38.private JTextField txt_hostlp;39.private JTextField txt_name;40.private JButton btn_start;41.private JButton btn_stop;42.private JButton btn_send;43.private JPanel northPanel;44.private JPanel southPanel;45.private JScrollPane rightScroll;46.private JScrol IPane leftScroll;47.private JSplitPane centerSplit;48.49.private DefaultListModel listModel;50.private booleanisConnected = false ;51.52.private Socket socket;53.private PrintWriter writer;54.private BufferedReader reader;55.private MessageThread messageThread;/负责接收消息的线程56.private Map onLineUsers =new HashMap ();/所有在线用户57.58./主方法,程序入口59.public static void main(String args) 60.new Client();61.62.63./执行发送64.public void send() 65.if disconnected) 66.JOptionPane.showMessageDialog(frame,还没有连接服务器,无法发送消息!,错误,67.JOptionPane.ERROR_MESSAGE);68.return;69.70.Stringmessage = textField .getText().trim();71.if (message = null | message.equals() 72.JOptionPane.showMessageDialog(frame,消息不能为空!,错误,73.JOptionPane.ERROR_MESSAGE);74.return;75.76.77.78.79.80.81.82.83.84.85.86.87.88.89.90.91.92.93.94.95.96.97.98.99.100.101.102.103.104.105.106.107.108.109.110.111.112.113.114.115.sendMessage(frame.getTitle() + + ALL + + mes sage);textField.setText(null);/ 构造方法public Client() textArea = new JTextArea();textArea.setEditable(false);textArea.setForeground(Color.blue);textField=new JTextField();txt_port=new JTextField(6666);txt_hostIp=new JTextField(127.0.0.1)txt_name=new JTextField(xiaoqiang);btn_start=new JButton( 连接);btn_stop=new JButton(断开);btn_send=new JButton( 发送);listModel=new DefaultListModel();userList=new JList(listModel);northPanel=new JPanel();northPanel.setLayout(new GridLayout(1, 7); northPanel.add(new JLabel(端口 );northPanel.add(txt_port);northPanel.add(new JLabel(服务器 IP);northPanel.add(txt_hostlp);northPanel.add(new JLabel(姓名);northPanel.add(txt_name); northPanel.add(btn_start);连接信息消息显示区在线用户写消息);northPanel.add(btn_stop); northPanel.setBorder(new TitledBorder(”);rightScroll = new JScrollPane(textArea); rightScroll.setBorder(new TitledBorder();leftScroll = new JScrollPane(userList); leftScroll.setBorder(new TitledBorder();southPanel = new JPanel(new BorderLayout(); southPanel.add(textField, Center); southPanel.add(btn_send, East); southPanel.setBorder(new TitledBorder(116.117.118.119.120.121.122.123.124.125.126.127.128.129.130.131.132.133.134.135.136.137.138.139.140.141.142.143.144.145.146.147.1
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 办公文档 > 解决方案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!