⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatserver.java

📁 java入门经典教程 java入门经典教程 java入门经典教程
💻 JAVA
字号:
// 例 8.5.2 ChatServer.java
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;

public class ChatServer extends JPanel 
{
    private JPanel topPanel = new JPanel();
    private JPanel buttomPanel = new JPanel();
    private DefaultTableModel defaultModel;
    private JTable nameTable;
    private JButton exitButton;
    private JList list;
    private DefaultListModel listModel;
    private JButton sendButton = new JButton("发送");
private JTextField sayWord = new JTextField();
// totalThread将所有的连接保存在其中,当需要时从中取出
    private Vector totalThread = new Vector();
    private int port = 8082;
    public ChatServer()
{
        this.setLayout(new GridLayout(2, 1));
    }
    public void init() 
{
        String[] columName = new String[] { "用户名称", "IP" };
        String[][] tempData = new String[][] { { "", "" } };

        defaultModel = new DefaultTableModel(tempData, columName);
        nameTable = new JTable(defaultModel);
        nameTable.setRowHeight(22);

        exitButton = new JButton("StopServer");
        exitButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        topPanel.setLayout(new BorderLayout());
        topPanel.add(new JLabel("在线用户", JLabel.LEFT), BorderLayout.NORTH);
        topPanel.add(new JScrollPane(nameTable), BorderLayout.CENTER);

        listModel = new DefaultListModel();
        list = new JList(listModel);

        JPanel temp = new JPanel(new BorderLayout());
        temp.add(sayWord, BorderLayout.CENTER);
        sendButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                sendData();
            }
        });
        temp.add(sendButton, BorderLayout.EAST);
        JPanel temp2 = new JPanel();
        temp2.add(exitButton);
        temp.add(temp2, BorderLayout.SOUTH);

        buttomPanel.setLayout(new BorderLayout());
        buttomPanel.add(new JScrollPane(list), BorderLayout.CENTER);
        buttomPanel.add(temp, BorderLayout.SOUTH);

        this.add(topPanel);
        this.add(buttomPanel);
        new StartServer().start();
        new UpdataThread().start();
    }
   // StartServer启动serverSocket等待在服务器上,为每一个请求创建一个线程
    class StartServer extends Thread 
{
        public void run() 
{
            try
{
                ServerSocket serverSocket = new ServerSocket(port);
                while (true) 
{
                    try
{
                        Socket socket = serverSocket.accept();
                        AcceptThread acceptThread = new AcceptThread(socket);
                        acceptThread.start();
                        totalThread.add(acceptThread);
                    } catch (IOException ex2) {
                        throw ex2;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
private void addWord(String word)
{
        listModel.add(0, word);
}
// sendData()用于将服务器的发言发送给每一个客户端,具体怎么发送由//sendWordToEveryone来完成
    private void sendData() 
{
        String temp = "服务器说:" + sayWord.getText().trim();
        sendWordToEveryone(temp.getBytes());
        addWord(temp);
}
// UpdataThread每隔6000毫秒检查在线用户并将信息显示在表格中
    class UpdataThread extends Thread 
{
        public void run()
{
            while (true)
{
                String[] columName = new String[] { "用户名称", "IP" };
                String[][] tempData = new String[][] {};
                defaultModel = new DefaultTableModel(tempData, columName);

                AcceptThread tempThread = null;
                Object tempObject = null;
                Enumeration enum = totalThread.elements();
                while (enum.hasMoreElements()) 
{
                    tempObject = enum.nextElement();
                    if (tempObject != null)
{
                        tempThread = (AcceptThread) tempObject;
                        if (tempThread.isAlive())
                            defaultModel.addRow(new String[] {
                                    tempThread.getUserName(),
                                    tempThread.getUserIP() });
                        else
                            tempObject = null;
                    }
                    //我们创建了新的DefaultTableModel,调用JTable 的setModel
//方法后,JTable将显示这个DefaultTableModel的内容
                    nameTable.setModel(defaultModel);
                }
                try
{
                    sleep(6000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) 
{
        JFrame mf = new JFrame("Chat Server");
        ChatServer server = new ChatServer();
        mf.getContentPane().add(server);
        mf.setLocation(150, 0);
        mf.setSize(450, 450);
        mf.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        server.init();
        mf.setVisible(true);
    }
 //serverSocket为每一个客户请求都会生成一个新的AcceptThread线程
    class AcceptThread extends Thread
{
        Socket socket = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        String name = "DefaultName";
        String ip;
        boolean flag = true;
        BufferedInputStream bis;
        BufferedOutputStream bos;
        byte[] bytes;
        public AcceptThread(Socket socket) 
{
            this.socket = socket;
            ip = socket.getInetAddress().getHostAddress();
            System.out.println(ip);
            try 
{
                inputStream = socket.getInputStream();
                outputStream = socket.getOutputStream();
                bos = new BufferedOutputStream(outputStream, 1024);
            } catch (IOException e) {
                e.printStackTrace();
                if (socket != null)
{
                    try
{
                        socket.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
                flag = false;
            }
        }
        public void run() 
{
            bis = new BufferedInputStream(inputStream, 1024);
            while (flag) 
{
                try
{
                    bytes = new byte[1024];
                    bis.read(bytes);
                    String tempS = new String(bytes);
                    tempS = tempS.trim();
                    name = tempS.substring(0, tempS.indexOf("说"));
                    addWord(tempS);
                    sendWordToEveryone(bytes);
                } catch (IOException e) {
                    e.printStackTrace();
                    flag = false;
                }
            }
        }
        //AcceptThread用sendWord来向和自己建立专线连接的客户发送数据
        public void sendWord(byte[] bytes)
 {
            try
{
                bos.write(bytes);
                bos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
// getUserName用于返回当前客户端的名称
        public String getUserName() 
{
            return name;
        }
// getUserName用于返回当前客户端的IP地址
        public String getUserIP()
{
            return ip;
        }
}
// sendWordToEveryone从totalThread中提取每一个AcceptThread并向活着的
//线程发送数据
    private void sendWordToEveryone(byte[] bytes) 
{
        Enumeration enum = totalThread.elements();
        while (enum.hasMoreElements())
{
            Object tempObject = enum.nextElement();
            if (tempObject != null) 
{
                AcceptThread tempThread = (AcceptThread) tempObject;
                if (tempThread.isAlive())
{
                    tempThread.sendWord(bytes);
                }
            }
        }
    }
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -