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

来自 , 2020-09-06, 写在 Java, 查看 196 次.
URL http://www.code666.cn/view/ede7e2b6
  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