[Java] 通信 chat server →→→→→进入此内容的聊天室

来自 , 2019-08-23, 写在 Java, 查看 153 次.
URL http://www.code666.cn/view/362e80d4
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. import javax.swing.*;
  4. import javax.swing.event.*;
  5. import java.net.*;
  6. import java.io.*;
  7.  
  8. /*
  9.  * 聊天服务端的主框架类
  10.  */
  11. public class ChatServer extends JFrame implements ActionListener{
  12.  
  13.         public static int port = 8888;//服务端的侦听端口
  14.  
  15.         ServerSocket serverSocket;//服务端Socket
  16.         Image icon;//程序图标
  17.         JComboBox combobox;//选择发送消息的接受者
  18.         JTextArea messageShow;//服务端的信息显示
  19.         JScrollPane messageScrollPane;//信息显示的滚动条
  20.         JTextField showStatus;//显示用户连接状态
  21.         JLabel sendToLabel,messageLabel;
  22.         JTextField sysMessage;//服务端消息的发送
  23.         JButton sysMessageButton;//服务端消息的发送按钮
  24.         UserLinkList userLinkList;//用户链表
  25.  
  26.         //建立菜单栏
  27.         JMenuBar jMenuBar = new JMenuBar();
  28.         //建立菜单组
  29.         JMenu serviceMenu = new JMenu ("服务(V)");
  30.         //建立菜单项
  31.         JMenuItem portItem = new JMenuItem ("端口设置(P)");
  32.         JMenuItem startItem = new JMenuItem ("启动服务(S)");
  33.         JMenuItem stopItem=new JMenuItem ("停止服务(T)");
  34.         JMenuItem exitItem=new JMenuItem ("退出(X)");
  35.        
  36.         JMenu helpMenu=new JMenu ("帮助(H)");
  37.         JMenuItem helpItem=new JMenuItem ("帮助(H)");
  38.  
  39.         //建立工具栏
  40.         JToolBar toolBar = new JToolBar();
  41.  
  42.         //建立工具栏中的按钮组件
  43.         JButton portSet;//启动服务端侦听
  44.         JButton startServer;//启动服务端侦听
  45.         JButton stopServer;//关闭服务端侦听
  46.         JButton exitButton;//退出按钮
  47.        
  48.         //框架的大小
  49.         Dimension faceSize = new Dimension(400, 600);
  50.        
  51.         ServerListen listenThread;
  52.  
  53.         JPanel downPanel ;
  54.         GridBagLayout girdBag;
  55.         GridBagConstraints girdBagCon;
  56.  
  57.  
  58.         /**
  59.          * 服务端构造函数
  60.          */
  61.         public ChatServer(){
  62.                 init();//初始化程序
  63.  
  64.                 //添加框架的关闭事件处理
  65.                 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  66.                 this.pack();
  67.                 //设置框架的大小
  68.                 this.setSize(faceSize);
  69.  
  70.                 //设置运行时窗口的位置
  71.                 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
  72.                 this.setLocation( (int) (screenSize.width - faceSize.getWidth()) / 2,
  73.                                                  (int) (screenSize.height - faceSize.getHeight()) / 2);
  74.                 this.setResizable(false);
  75.  
  76.                 this.setTitle("聊天室服务端"); //设置标题
  77.  
  78.                 //程序图标
  79.                 icon = getImage("icon.gif");
  80.                 this.setIconImage(icon); //设置程序图标
  81.                 show();
  82.  
  83.                 //为服务菜单栏设置热键'V'
  84.                 serviceMenu.setMnemonic('V');
  85.  
  86.                 //为端口设置快捷键为ctrl+p
  87.                 portItem.setMnemonic ('P');
  88.                 portItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_P,InputEvent.CTRL_MASK));
  89.  
  90.                 //为启动服务快捷键为ctrl+s
  91.                 startItem.setMnemonic ('S');
  92.                 startItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_S,InputEvent.CTRL_MASK));
  93.  
  94.                 //为端口设置快捷键为ctrl+T
  95.                 stopItem.setMnemonic ('T');
  96.                 stopItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_T,InputEvent.CTRL_MASK));
  97.  
  98.                 //为退出设置快捷键为ctrl+x
  99.                 exitItem.setMnemonic ('X');
  100.                 exitItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_X,InputEvent.CTRL_MASK));
  101.  
  102.                 //为帮助菜单栏设置热键'H'
  103.                 helpMenu.setMnemonic('H');
  104.  
  105.                 //为帮助设置快捷键为ctrl+p
  106.                 helpItem.setMnemonic ('H');
  107.                 helpItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_H,InputEvent.CTRL_MASK));
  108.  
  109.         }
  110.        
  111.         /**
  112.          * 程序初始化函数
  113.          */
  114.         public void init(){
  115.  
  116.                 Container contentPane = getContentPane();
  117.                 contentPane.setLayout(new BorderLayout());
  118.  
  119.                 //添加菜单栏
  120.                 serviceMenu.add (portItem);
  121.                 serviceMenu.add (startItem);
  122.                 serviceMenu.add (stopItem);
  123.                 serviceMenu.add (exitItem);
  124.                 jMenuBar.add (serviceMenu);
  125.                 helpMenu.add (helpItem);
  126.                 jMenuBar.add (helpMenu);
  127.                 setJMenuBar (jMenuBar);
  128.  
  129.                 //初始化按钮
  130.                 portSet = new JButton("端口设置");
  131.                 startServer = new JButton("启动服务");
  132.                 stopServer = new JButton("停止服务" );
  133.                 exitButton = new JButton("退出" );
  134.                 //将按钮添加到工具栏
  135.                 toolBar.add(portSet);
  136.                 toolBar.addSeparator();//添加分隔栏
  137.                 toolBar.add(startServer);
  138.                 toolBar.add(stopServer);
  139.                 toolBar.addSeparator();//添加分隔栏
  140.                 toolBar.add(exitButton);
  141.                 contentPane.add(toolBar,BorderLayout.NORTH);
  142.  
  143.                 //初始时,令停止服务按钮不可用
  144.                 stopServer.setEnabled(false);
  145.                 stopItem .setEnabled(false);
  146.  
  147.                 //为菜单栏添加事件监听
  148.                 portItem.addActionListener(this);
  149.                 startItem.addActionListener(this);
  150.                 stopItem.addActionListener(this);
  151.                 exitItem.addActionListener(this);
  152.                 helpItem.addActionListener(this);
  153.                
  154.                 //添加按钮的事件侦听
  155.                 portSet.addActionListener(this);
  156.                 startServer.addActionListener(this);
  157.                 stopServer.addActionListener(this);
  158.                 exitButton.addActionListener(this);
  159.                
  160.                 combobox = new JComboBox();
  161.                 combobox.insertItemAt("所有人",0);
  162.                 combobox.setSelectedIndex(0);
  163.                
  164.                 messageShow = new JTextArea();
  165.                 messageShow.setEditable(false);
  166.                 //添加滚动条
  167.                 messageScrollPane = new JScrollPane(messageShow,
  168.                         JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
  169.                         JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
  170.                 messageScrollPane.setPreferredSize(new Dimension(400,400));
  171.                 messageScrollPane.revalidate();
  172.                
  173.                 showStatus = new JTextField(35);
  174.                 showStatus.setEditable(false);
  175.                
  176.                 sysMessage = new JTextField(24);
  177.                 sysMessage.setEnabled(false);
  178.                 sysMessageButton = new JButton();
  179.                 sysMessageButton.setText("发送");
  180.  
  181.                 //添加系统消息的事件侦听
  182.                 sysMessage.addActionListener(this);
  183.                 sysMessageButton.addActionListener(this);
  184.  
  185.                 sendToLabel = new JLabel("发送至:");
  186.                 messageLabel = new JLabel("发送消息:");
  187.                 downPanel = new JPanel();
  188.                 girdBag = new GridBagLayout();
  189.                 downPanel.setLayout(girdBag);
  190.  
  191.                 girdBagCon = new GridBagConstraints();
  192.                 girdBagCon.gridx = 0;
  193.                 girdBagCon.gridy = 0;
  194.                 girdBagCon.gridwidth = 3;
  195.                 girdBagCon.gridheight = 2;
  196.                 girdBagCon.ipadx = 5;
  197.                 girdBagCon.ipady = 5;
  198.                 JLabel none = new JLabel("    ");
  199.                 girdBag.setConstraints(none,girdBagCon);
  200.                 downPanel.add(none);
  201.  
  202.                 girdBagCon = new GridBagConstraints();
  203.                 girdBagCon.gridx = 0;
  204.                 girdBagCon.gridy = 2;
  205.                 girdBagCon.insets = new Insets(1,0,0,0);
  206.                 girdBagCon.ipadx = 5;
  207.                 girdBagCon.ipady = 5;
  208.                 girdBag.setConstraints(sendToLabel,girdBagCon);
  209.                 downPanel.add(sendToLabel);
  210.  
  211.                 girdBagCon = new GridBagConstraints();
  212.                 girdBagCon.gridx =1;
  213.                 girdBagCon.gridy = 2;
  214.                 girdBagCon.anchor = GridBagConstraints.LINE_START;
  215.                 girdBag.setConstraints(combobox,girdBagCon);
  216.                 downPanel.add(combobox);
  217.  
  218.                 girdBagCon = new GridBagConstraints();
  219.                 girdBagCon.gridx = 0;
  220.                 girdBagCon.gridy = 3;
  221.                 girdBag.setConstraints(messageLabel,girdBagCon);
  222.                 downPanel.add(messageLabel);
  223.  
  224.                 girdBagCon = new GridBagConstraints();
  225.                 girdBagCon.gridx = 1;
  226.                 girdBagCon.gridy = 3;
  227.                 girdBag.setConstraints(sysMessage,girdBagCon);
  228.                 downPanel.add(sysMessage);
  229.  
  230.                 girdBagCon = new GridBagConstraints();
  231.                 girdBagCon.gridx = 2;
  232.                 girdBagCon.gridy = 3;
  233.                 girdBag.setConstraints(sysMessageButton,girdBagCon);
  234.                 downPanel.add(sysMessageButton);
  235.  
  236.                 girdBagCon = new GridBagConstraints();
  237.                 girdBagCon.gridx = 0;
  238.                 girdBagCon.gridy = 4;
  239.                 girdBagCon.gridwidth = 3;
  240.                 girdBag.setConstraints(showStatus,girdBagCon);
  241.                 downPanel.add(showStatus);
  242.  
  243.                 contentPane.add(messageScrollPane,BorderLayout.CENTER);
  244.                 contentPane.add(downPanel,BorderLayout.SOUTH);
  245.                
  246.                 //关闭程序时的操作
  247.                 this.addWindowListener(
  248.                         new WindowAdapter(){
  249.                                 public void windowClosing(WindowEvent e){
  250.                                         stopService();
  251.                                         System.exit(0);
  252.                                 }
  253.                         }
  254.                 );
  255.         }
  256.  
  257.         /**
  258.          * 事件处理
  259.          */
  260.         public void actionPerformed(ActionEvent e) {
  261.                 Object obj = e.getSource();
  262.                 if (obj == startServer || obj == startItem) { //启动服务端
  263.                         startService();
  264.                 }
  265.                 else if (obj == stopServer || obj == stopItem) { //停止服务端
  266.                         int j=JOptionPane.showConfirmDialog(
  267.                                 this,"真的停止服务吗?","停止服务",
  268.                                 JOptionPane.YES_OPTION,JOptionPane.QUESTION_MESSAGE);
  269.                        
  270.                         if (j == JOptionPane.YES_OPTION){
  271.                                 stopService();
  272.                         }
  273.                 }
  274.                 else if (obj == portSet || obj == portItem) { //端口设置
  275.                         //调出端口设置的对话框
  276.                         PortConf portConf = new PortConf(this);
  277.                         portConf.show();
  278.                 }
  279.                 else if (obj == exitButton || obj == exitItem) { //退出程序
  280.                         int j=JOptionPane.showConfirmDialog(
  281.                                 this,"真的要退出吗?","退出",
  282.                                 JOptionPane.YES_OPTION,JOptionPane.QUESTION_MESSAGE);
  283.                        
  284.                         if (j == JOptionPane.YES_OPTION){
  285.                                 stopService();
  286.                                 System.exit(0);
  287.                         }
  288.                 }
  289.                 else if (obj == helpItem) { //菜单栏中的帮助
  290.                         //调出帮助对话框
  291.                         Help helpDialog = new Help(this);
  292.                         helpDialog.show();
  293.                 }
  294.                 else if (obj == sysMessage || obj == sysMessageButton) { //发送系统消息
  295.                         sendSystemMessage();
  296.                 }
  297.         }
  298.        
  299.         /**
  300.          * 启动服务端
  301.          */
  302.         public void startService(){
  303.                 try{
  304.                         serverSocket = new ServerSocket(port,10);
  305.                         messageShow.append("服务端已经启动,在"+port+"端口侦听...\n");
  306.                        
  307.                         startServer.setEnabled(false);
  308.                         startItem.setEnabled(false);
  309.                         portSet.setEnabled(false);
  310.                         portItem.setEnabled(false);
  311.  
  312.                         stopServer .setEnabled(true);
  313.                         stopItem .setEnabled(true);
  314.                         sysMessage.setEnabled(true);
  315.                 }
  316.                 catch (Exception e){
  317.                         //System.out.println(e);
  318.                 }
  319.                 userLinkList = new UserLinkList();
  320.                
  321.                 listenThread = new ServerListen(serverSocket,combobox,
  322.                         messageShow,showStatus,userLinkList);
  323.                 listenThread.start();
  324.         }
  325.        
  326.         /**
  327.          * 关闭服务端
  328.          */
  329.         public void stopService(){
  330.                 try{
  331.                         //向所有人发送服务器关闭的消息
  332.                         sendStopToAll();
  333.                         listenThread.isStop = true;
  334.                         serverSocket.close();
  335.                        
  336.                         int count = userLinkList.getCount();
  337.                        
  338.                         int i =0;
  339.                         while( i < count){
  340.                                 Node node = userLinkList.findUser(i);
  341.                                
  342.                                 node.input .close();
  343.                                 node.output.close();
  344.                                 node.socket.close();
  345.                                
  346.                                 i ++;
  347.                         }
  348.  
  349.                         stopServer .setEnabled(false);
  350.                         stopItem .setEnabled(false);
  351.                         startServer.setEnabled(true);
  352.                         startItem.setEnabled(true);
  353.                         portSet.setEnabled(true);
  354.                         portItem.setEnabled(true);
  355.                         sysMessage.setEnabled(false);
  356.  
  357.                         messageShow.append("服务端已经关闭\n");
  358.  
  359.                         combobox.removeAllItems();
  360.                         combobox.addItem("所有人");
  361.                 }
  362.                 catch(Exception e){
  363.                         //System.out.println(e);
  364.                 }
  365.         }
  366.        
  367.         /**
  368.          * 向所有人发送服务器关闭的消息
  369.          */
  370.         public void sendStopToAll(){
  371.                 int count = userLinkList.getCount();
  372.                
  373.                 int i = 0;
  374.                 while(i < count){
  375.                         Node node = userLinkList.findUser(i);
  376.                         if(node == null) {
  377.                                 i ++;
  378.                                 continue;
  379.                         }
  380.                        
  381.                         try{
  382.                                 node.output.writeObject("服务关闭");
  383.                                 node.output.flush();
  384.                         }
  385.                         catch (Exception e){
  386.                                 //System.out.println("$$$"+e);
  387.                         }
  388.                        
  389.                         i++;
  390.                 }
  391.         }
  392.        
  393.         /**
  394.          * 向所有人发送消息
  395.          */
  396.         public void sendMsgToAll(String msg){
  397.                 int count = userLinkList.getCount();//用户总数
  398.                
  399.                 int i = 0;
  400.                 while(i < count){
  401.                         Node node = userLinkList.findUser(i);
  402.                         if(node == null) {
  403.                                 i ++;
  404.                                 continue;
  405.                         }
  406.                        
  407.                         try{
  408.                                 node.output.writeObject("系统信息");
  409.                                 node.output.flush();
  410.                                 node.output.writeObject(msg);
  411.                                 node.output.flush();
  412.                         }
  413.                         catch (Exception e){
  414.                                 //System.out.println("@@@"+e);
  415.                         }
  416.                        
  417.                         i++;
  418.                 }
  419.  
  420.                 sysMessage.setText("");
  421.         }
  422.  
  423.         /**
  424.          * 向客户端用户发送消息
  425.          */
  426.         public void sendSystemMessage(){
  427.                 String toSomebody = combobox.getSelectedItem().toString();
  428.                 String message = sysMessage.getText() + "\n";
  429.                
  430.                 messageShow.append(message);
  431.                
  432.                 //向所有人发送消息
  433.                 if(toSomebody.equalsIgnoreCase("所有人")){
  434.                         sendMsgToAll(message);
  435.                 }
  436.                 else{
  437.                         //向某个用户发送消息
  438.                         Node node = userLinkList.findUser(toSomebody);
  439.                        
  440.                         try{
  441.                                 node.output.writeObject("系统信息");
  442.                                 node.output.flush();
  443.                                 node.output.writeObject(message);
  444.                                 node.output.flush();
  445.                         }
  446.                         catch(Exception e){
  447.                                 //System.out.println("!!!"+e);
  448.                         }
  449.                         sysMessage.setText("");//将发送消息栏的消息清空
  450.                 }
  451.         }
  452.  
  453.         /**
  454.          * 通过给定的文件名获得图像
  455.          */
  456.         Image getImage(String filename) {
  457.                 URLClassLoader urlLoader = (URLClassLoader)this.getClass().
  458.                         getClassLoader();
  459.                 URL url = null;
  460.                 Image image = null;
  461.                 url = urlLoader.findResource(filename);
  462.                 image = Toolkit.getDefaultToolkit().getImage(url);
  463.                 MediaTracker mediatracker = new MediaTracker(this);
  464.                 try {
  465.                         mediatracker.addImage(image, 0);
  466.                         mediatracker.waitForID(0);
  467.                 }
  468.                 catch (InterruptedException _ex) {
  469.                         image = null;
  470.                 }
  471.                 if (mediatracker.isErrorID(0)) {
  472.                         image = null;
  473.                 }
  474.  
  475.                 return image;
  476.         }
  477.  
  478.         public static void main(String[] args) {
  479.                 ChatServer app = new ChatServer();
  480.         }
  481. }
  482.  

回复 "通信 chat server"

这儿你可以回复上面这条便签

captcha