java实现基于TCP协议带界面的多人聊天代码

来源:互联网 发布:景区系统源码 编辑:程序博客网 时间:2024/05/17 06:34

====================客服端的代码=====================

package TCP;import java.awt.FlowLayout;import java.awt.GridBagConstraints;import java.awt.GridBagLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JTextArea;import javax.swing.JTextField;/* * 客服端接收信息 */class recvMsg implements Runnable{    private Socket s;    private JTextArea messageArea;    recvMsg(Socket s){        this.s = s;        this.messageArea = setMenu.messageArea;    }    @Override    public void run() {        //定义一个Socket读取流,读取服务器端返回的信息                BufferedReader bufIn = null;                System.out.println("-------rev----------");                while(true){                    try {                        bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));                    } catch (IOException e1) {                        System.out.println("接收信息失败");                        e1.printStackTrace();                    }                    try {                        String recvMsg = bufIn.readLine();                        messageArea.append(recvMsg+"\r\n");                    } catch (IOException e) {                        e.printStackTrace();                    }                }    }}/*** 创建GUI界面的类*/class setMenu {    static JFrame f;    static JButton btn_send;    static JButton btn_clear;    static JButton btn_close;    static JTextField txf_name;    static JTextField txf_send;    static JTextArea messageArea;     Socket s;    setMenu(Socket s){        this.s = s;        createMenu();        someListener();    }/*** 相关事件监听操作* */    private void someListener() {        btn_send.addActionListener(new SendMsg3(s));        btn_close.addActionListener(new ActionListener() {            @Override            public void actionPerformed(ActionEvent e) {                System.exit(0);            }        });        txf_send.addKeyListener(new SendMsg3(s));        btn_clear.addActionListener(new ActionListener() {            @Override            public void actionPerformed(ActionEvent e) {                txf_send.setText("");            }        });        messageArea.addKeyListener(new KeyAdapter() {            @Override            public void keyTyped(KeyEvent e) {                e.consume();// 屏蔽掉法输入            }        });    }    private void createMenu() {    f = new JFrame("聊天");    f.setBounds(50, 50, 700, 600);    f.setLayout(new GridBagLayout());    JPanel panel_Name = new JPanel();    JLabel label_name = new JLabel("名字:");    txf_name = new JTextField(10);    panel_Name.add(label_name);    panel_Name.add(txf_name);    GridBagConstraints gbc_name = new GridBagConstraints();// 创建网格组布局约束条件    gbc_name.gridx = 2;    gbc_name.gridy = 0;    messageArea = new JTextArea("", 20, 50);    GridBagConstraints gbc_msg = new GridBagConstraints();    gbc_msg.gridx = 0;    gbc_msg.gridy = 1;    gbc_msg.gridwidth = 3;      JPanel panel_send = new JPanel(new FlowLayout());    JLabel label_send = new JLabel("发送内容:");    txf_send = new JTextField(30);    panel_send.add(label_send);    panel_send.add(txf_send);    GridBagConstraints gbc_send = new GridBagConstraints();    gbc_send.gridx = 0;    gbc_send.gridy = 2;    JPanel panel_button = new JPanel(new FlowLayout());    btn_send = new JButton("发送");    btn_clear = new JButton("清除");    btn_close = new JButton("关闭");    panel_button.add(btn_send);    panel_button.add(btn_clear);    panel_button.add(btn_close);    GridBagConstraints gbc_button = new GridBagConstraints();    gbc_button.fill = GridBagConstraints.BOTH;    gbc_button.gridx = 0;    gbc_button.gridy = 3;    f.add(panel_Name,gbc_name);    f.add(messageArea,gbc_msg);    f.add(panel_send,gbc_send);    f.add(panel_button,gbc_button);    f.setVisible(true);    }    class SendMsg3 implements ActionListener, KeyListener {        Socket s;        SendMsg3(Socket s){            this.s =  s;        }        @Override        public void keyTyped(KeyEvent e) {            // TODO Auto-generated method stub        }        @Override        public void keyPressed(KeyEvent e) {            if (e.getKeyCode() == e.VK_ENTER) {                sendMsg();            }        }        @Override        public void keyReleased(KeyEvent e) {            // TODO Auto-generated method stub        }        @Override        public void actionPerformed(ActionEvent e) {            sendMsg();        }        /**         * 发送信息         */        private void sendMsg() {            // 如果名字为空 给出提示信息            if(txf_name.getText().isEmpty()){                new JOptionPane().showMessageDialog(null, "请一定要取别名!");            }            String line = txf_name.getText() + ": "+txf_send.getText();            try {                if (!line.isEmpty()) {                    //下面PrintWriter是可以自带刷新缓存工作,可以简化写入流的操作,                    PrintWriter pout = new PrintWriter(s.getOutputStream(),true);                    pout.println(line);                    System.out.print("input:"+line);                    txf_send.setText("");                } else {                    System.out.println("发送数据不为空,请重新输入");                    new JOptionPane().showMessageDialog(null, "发送数据不为空,请重新输入!");                }            } catch (Exception e1) {                // TODO Auto-generated catch block                System.out.println("发送失败");                e1.printStackTrace();            }        }    }}/** * 客服端 */public class TCPClient {    static JFrame f;    static JButton btn_send;    static JButton btn_clear;    static JButton btn_close;    static JTextField txf_name;    static JTextField txf_send;    static JTextArea messageArea;    static Socket s;    public static void main(String[] args) {        //连接服务器        connetServer();        //设计GUI界面        new setMenu(s);        //启动接收数据线程        new Thread(new recvMsg(s)).start();    }    /**     * 连接服务器     */    private static void connetServer() {        //创建客服端的Socket服务,指定目的主机和端口        try {        //"10.136.128.26"是访问服务器的IP地址,30001是端口号            s = new Socket("10.136.128.26",30001);        } catch (Exception e) {            System.out.println("客服端连接服务器失败");            e.printStackTrace();        }                   }}

===================服务器端的代码======================

package TCP;/* * 服务器 */import java.io.*;import java.net.*;import java.util.ArrayList;public class TCPServer {             //创建一个集合,集合存放客服端的对象    ArrayList<Socket> arrayListSocket = new ArrayList<Socket>();    boolean listener = true;    TCPServer() {        System.out.println("------监听---------");        ServerSocket ss;        try {            ss = new ServerSocket(30001);            while (listener) {                                //等待客服端连接,一旦有客服端连接服务器,将客服端对象存放到集合中                Socket socket = ss.accept();                arrayListSocket.add(socket);                String ip = socket.getInetAddress().getHostAddress();                System.out.println("ip: " + ip + " 上线了!");                new Thread(new acceptClient(socket, ip)).start();            }        } catch (IOException e) {            e.printStackTrace();        }    }    class acceptClient implements Runnable {        Socket s;        String ip;        acceptClient(Socket s, String ip) {            this.s = s;            this.ip = ip;        }        @Override        public void run() {            try {                // 通知用户上线消息                for (int i = 0; i < arrayListSocket.size(); i++) {                    Socket client = arrayListSocket.get(i);                    // 下面PrintWriter是可以自带刷新缓存工作,可以简化写入流的操作,                    PrintWriter pout = new PrintWriter(                            client.getOutputStream(), true);                    pout.println(ip + "上线了!!!");                }                while (listener) {                    // 读取Socket读取流中的数据                    BufferedReader bufIn = new BufferedReader(                            new InputStreamReader(s.getInputStream()));                    String line = bufIn.readLine();                    // 下面PrintWriter是可以自带刷新缓存工作,可以简化写入流的操作,                    //通过for()循序服务器将数据发送的arrayListSocket集合中所有客服端                    for (int i = 0; i < arrayListSocket.size(); i++) {                        Socket client = arrayListSocket.get(i);                        PrintWriter pout = new PrintWriter(                                client.getOutputStream(), true);                        pout.println(line);                    }                }            } catch (IOException e) {                System.out.println("接受:" + s.getInetAddress() + " 信息失败");                e.printStackTrace();            }        }    }    public static void main(String[] args) throws Exception, IOException {        //创建服务器对象        new TCPServer();    }}

如图:其中一个客服端的聊天窗口
这里写图片描述

0 0
原创粉丝点击