Java实现简易聊天室

在学习《Java从入门到精通》这本书,网络通信,基于TCP实现的简易聊天室,我这里对书中的代码略做了修改,做个记录。

 

这里先放一下运行效果图,代码放在最后。

 

运行效果:

先启动服务器端:

开源实时聊天 java java开发聊天室_java

 

 

启动客户端:

开源实时聊天 java java开发聊天室_开源实时聊天 java_02

 

发送数据:

开源实时聊天 java java开发聊天室_开源实时聊天 java_03

 

 

主要的功能就是上面那些,在代码中我还添加一些功能,比如说给JTextField添加了焦点监听器,以及输入框为空的检查和提示,但总的来说还是比较简单,如果要实现健壮的聊天室程序还需要再做些修改。

 

下面放下代码,比较简单,就服务器端和客户端两个代码。

 

服务器端代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import static java.lang.System.out;

public class MyTcp {
    
    private BufferedReader reader;
    private ServerSocket server;
    private Socket socket;
    
    void getServer(){
        try {
            server=new ServerSocket(8998);        //实例化Socket对象
            out.println("服务器套接字已创建成功");
            
            while(true) {
                out.println("等待客户机的连接");
                socket=server.accept();           //accept()方法会返回一个和客户端Socket对象相连的Socket对象
                reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                getClientMessage();
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    //读取客户端发送过来的信息
    private void getClientMessage() {
        try {
            while(true) {
                //获得客户端信息
                out.println("客户机:"+reader.readLine());
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
        try {
            if(reader!=null) {
                reader.close();
            }
            if(socket!=null) {
                socket.close();
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

    
    public static void main(String[] args) {
        MyTcp tcp=new  MyTcp();
        tcp.getServer();
    }

}

 

 

 

客户端代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.PrintWriter;
import java.net.Socket;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;

public class MyClient extends JFrame{
    
    private PrintWriter writer;
    Socket socket;
    private JTextArea ta=new JTextArea();
    private JTextField tf=new JTextField();
    Container cc;
    
    public MyClient(String title) {
        super(title);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        cc=this.getContentPane();
        
        final JScrollPane scrollPane=new JScrollPane();
        scrollPane.setBorder(new BevelBorder(BevelBorder.RAISED));
        getContentPane().add(scrollPane,BorderLayout.CENTER);
        scrollPane.setViewportView(ta);
        cc.add(tf,"South");
        
        tf.addFocusListener(new JTextFieldListener(tf,"请在此输入内容"));
        tf.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(tf.getText().isEmpty()) {
                    JOptionPane.showMessageDialog(MyClient.this, "请输入内容!");
                }else {
                    writer.println(tf.getText());
                    
                    ta.append(tf.getText()+"\n");
                    ta.setSelectionEnd(ta.getText().length());
                    tf.setText("");
                }
                
                
            }
        });
    }
    
    //焦点监听器
    class JTextFieldListener implements FocusListener{
        
        private String hintText;          //提示文字
        private JTextField textField;
        
        public JTextFieldListener(JTextField textField,String hintText) {
            this.textField=textField;
            this.hintText=hintText;
            textField.setText(hintText);   //默认直接显示
            textField.setForeground(Color.GRAY);
        }

        @Override
        public void focusGained(FocusEvent e) {
            
            //获取焦点时,清空提示内容
            String temp=textField.getText();
            if(temp.equals(hintText)){
                textField.setText("");
                textField.setForeground(Color.BLACK);
            }
            
        }

        @Override
        public void focusLost(FocusEvent e) {
            
            //失去焦点时,没有输入内容,显示提示内容
            String temp=textField.getText();
            if(temp.equals("")) {
                textField.setForeground(Color.GRAY);
                textField.setText(hintText);
            }
            
        }
        
    }
    
    private void connect() {
        ta.append("尝试连接\n");
        try {
            socket=new Socket("127.0.0.1",8998);
            writer=new PrintWriter(socket.getOutputStream(),true);
            
            ta.append("完成连接\n");
            
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        
        //EventQueue事件队列,封装了异步事件指派机制
        EventQueue.invokeLater(new Runnable(){
            public void run() {
                MyClient client=new MyClient("向服务器发送数据");
                client.setSize(400,400);
                client.setVisible(true);
                client.connect();
                
                
            }
        });

    }

}

 

 

启动的时候要注意先启动服务器端再启动客户端,不然会报错。

 

 

 

 

 

菜鸟还需要不断学习。