Java实现简单QQ聊天工具

 更新时间:2022年09月16日 09:41:53   作者:发光吖  
这篇文章主要为大家详细介绍了Java实现简单QQ聊天工具,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

Java实现简单的类似QQ聊天工具,供大家参考,具体内容如下

所使用到的知识点:

  • java socket编程之TCP协议
  • java Swing
  • 简单的java多线程

运行截图:

服务器端实现:

package tcp_server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @author 乔澳
 * @version 1.0
 * @title: ServerThread
 * @projectName 20200222TCPServer
 * @description:
 * @date 2020/2/27   8:58
 */
public class ServerThread extends Thread{
    private User user;
    public ServerThread(User user){
        this.user = user;
    }
    @Override
    public void run() {
        Map<String, User> userMap = Server.userMap;
        Set<String> keys = userMap.keySet();
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(user.getSocket().getInputStream()));
            while (true) {
                String value = reader.readLine();// 客户端发来的一句话
                String[] valueAndUser = value.split("@");
                //群聊
                if (valueAndUser.length == 1) {
                    Iterator<String> it = keys.iterator();
                    while (it.hasNext()) {
                        String key = it.next();
                        User u = userMap.get(key);
                        PrintWriter pw = new PrintWriter(u.getSocket().getOutputStream());
                        pw.println(user.getUsername() + ":" + value + "(来自群消息)");
                        pw.flush();
                    }
                } else {
                    //单聊
                    for (int i = 1; i < valueAndUser.length; i++) {
                        String username = valueAndUser[i];
                        User u = userMap.get(username);
                        PrintWriter pw = new PrintWriter(u.getSocket().getOutputStream());
                        pw.println(user.getUsername() + ":" + valueAndUser[0] + "(来自私聊)");
                        pw.flush();
                    }
                }
            }
        } catch (IOException e) {
            System.out.println(user.getUsername()+"下线了");
        }
    }
}
package tcp_server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 乔澳
 * @version 1.0
 * @title: Server
 * @projectName 20200222TCPServer
 * @description:
 * @date 2020/2/25   9:12
 */
public class Server {
    static Map<String,User> userMap = new HashMap<String, User>();
    public static void main(String[] args) {
        try {
            System.out.println("===server start===");
            ServerSocket server = new ServerSocket(9999);
            while(true) {
                Socket socket = server.accept();

                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String username = br.readLine();
                User user = new User(username,socket);
                System.out.println(user.getUsername()+"上线啦");
                userMap.put(username,user);
                ServerThread thread = new ServerThread(user);
                thread.start();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}
package tcp_server;

import java.net.Socket;

/**
 * @author 乔澳
 * @version 1.0
 * @title: User
 * @projectName 20200222TCPServer
 * @description:
 * @date 2020/2/27   8:23
 */
public class User {
    public User(String username, Socket socket) {
        this.username = username;
        this.socket = socket;
    }
    private String username;
    private Socket socket;

    public User() {
    }

    public String getUsername() {
        return username;
    }

    public Socket getSocket() {
        return socket;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }
}

客户端实现:

package tcp_client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * @author 乔澳
 * @version 1.0
 * @title: ClientReader
 * @projectName 20200222TCPClient
 * @description:
 * @date 2020/2/26   16:11
 */
public class ClientReader extends Thread {
    private Socket socket;
    public ClientReader(Socket socket){
        this.socket = socket;
    }
    public void run(){
        try {
            InputStream is = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader reader = new BufferedReader(isr);
            for(;;){
                String value = reader.readLine();
                System.out.println(value);
            }
        } catch (IOException e) {
            System.out.println("对不起,服务器崩溃了");
        }
    }
}
package tcp_client;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

/**
 * @author 乔澳
 * @version 1.0
 * @title: ClientWriter
 * @projectName 20200222TCPClient
 * @description:
 * @date 2020/2/26   16:11
 */
public class ClientWriter extends Thread{
    private Socket socket;
    public ClientWriter(Socket socket){
        this.socket = socket;
    }
    public void run(){
        try {
            Scanner input = new Scanner(System.in);
            OutputStream os = socket.getOutputStream();
            PrintWriter pw = new PrintWriter(os);
            while(true) {
                System.out.println("说点什么吧:");
                String msg = input.nextLine();
                pw.println(msg);
                pw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
package tcp_client;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;

/**
 * @author 乔澳
 * @version 1.0
 * @title: QQFrame
 * @projectName 20200222TCPClient
 * @description:
 * @date 2020/2/28   9:46
 */
public class QQFrame extends JFrame{
    private String name;
    private JPanel panel = new JPanel();
    private JTextArea mesgArea = new JTextArea();
    private JScrollPane mesgPane = new JScrollPane(mesgArea);
    private JTextArea speakArea = new JTextArea();
    private JScrollPane speakPane = new JScrollPane(speakArea);
    private JButton sendBtn = new JButton("发送");
    private JButton resetBtn = new JButton("取消");
    private Socket socket;

    public QQFrame(String name){
        super(name);
        this.name = name;
        this.initOther();
        this.initElement();
        this.initSelf();
        this.connectServer();
        this.startReader();
        this.initListener();
    }
    private void connectServer(){
        System.out.println("===client start===");
        try {
            socket = new Socket("127.0.0.1",9999);
            PrintWriter pw = new PrintWriter(socket.getOutputStream());
            pw.println(name);
            pw.flush();
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this,"服务器连接失败");
            //e.printStackTrace();
        }
    }
    private void startReader(){
        //启动"读"线程
        ClientReader reader = new ClientReader();
        reader.start();
    }
    private void initListener(){
        ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    OutputStream os = socket.getOutputStream();
                    PrintWriter pw = new PrintWriter(os);
                    String msg = speakArea.getText();
                    if(msg.isEmpty())
                        return;
                    pw.println(msg);
                    pw.flush();
                    speakArea.setText("");
                } catch (IOException ee) {
                    ee.printStackTrace();
                }
            }
        };

        sendBtn.addActionListener(listener);

        resetBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                speakArea.setText("");
            }
        });
    }
    private void initOther(){
        panel.setLayout(null);
        mesgArea.setEditable(false);
        mesgPane.setBounds(10,10,305,220);
        speakPane.setBounds(10,240,305,140);
        sendBtn.setBounds(180,390,60,30);
        resetBtn.setBounds(260,390,60,30);
    }
    private void initElement(){
        panel.add(mesgPane);
        panel.add(speakPane);
        panel.add(sendBtn);
        panel.add(resetBtn);
        this.add(panel);
    }
    private void initSelf(){
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBounds(1400,220,350,500);
        this.setVisible(true);
    }


    public static void main(String[] args) {
        new QQFrame("乔乔");
        new QQFrame("小红");
        new QQFrame("小明");
    }


    //内部类
    public class ClientReader extends Thread {
        StringBuffer sb = new StringBuffer();
        public void run(){
            try {
                if(socket!=null) {
                    InputStream is = socket.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader reader = new BufferedReader(isr);
                    for (; ; ) {
                        String value = reader.readLine();
                        sb.append(value + "\n");
                        mesgArea.setText(sb.toString());
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Spring学习笔记之bean的基础知识

    Spring学习笔记之bean的基础知识

    ean在Spring和SpringMVC中无所不在,将这个概念内化很重要,所以下面这篇文章主要给大家介绍了关于Spring学习笔记之bean基础的相关资料,文中通过示例代码介绍的非常详解,需要的朋友可以参考下。
    2017-12-12
  • RocketMQ4.5.2 修改mqnamesrv 和 mqbroker的日志路径操作

    RocketMQ4.5.2 修改mqnamesrv 和 mqbroker的日志路径操作

    这篇文章主要介绍了RocketMQ 4.5.2 修改mqnamesrv 和 mqbroker的日志路径操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Java利用TreeUtils工具类实现列表转树

    Java利用TreeUtils工具类实现列表转树

    在开发过程中,总有列表转树的需求,几乎是项目的标配,有没有一种通用且跨项目的解决方式呢?本文将基于Java8的Lambda 表达式和Stream等知识,使用TreeUtils工具类实现一行代码完成列表转树这一通用型需求,需要的可以参考一下
    2022-11-11
  • SpringCloud组件之Eureka Server详细启动过程及说明

    SpringCloud组件之Eureka Server详细启动过程及说明

    这篇文章主要介绍了SpringCloud组件之Eureka Server详细启动过程及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 用SpringBoot Admin监控SpringBoot程序

    用SpringBoot Admin监控SpringBoot程序

    这篇文章主要介绍了用SpringBoot Admin监控SpringBoot程序,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下
    2020-10-10
  • SpringBoot+Redis实现布隆过滤器的示例代码

    SpringBoot+Redis实现布隆过滤器的示例代码

    本文主要介绍了SpringBoot+Redis实现布隆过滤器的示例代码,文中根据实例编码详细介绍的十分详尽,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 深入jetty的使用详解

    深入jetty的使用详解

    本篇文章是对jetty的使用进行了详细的分析解释。需要的朋友参考下
    2013-05-05
  • 详解Struts2拦截器机制

    详解Struts2拦截器机制

    这篇文章主要介绍了详解Struts2拦截器机制,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • 使用Springboot对配置文件中的敏感信息加密

    使用Springboot对配置文件中的敏感信息加密

    这篇文章主要介绍了使用Springboot对配置文件中的敏感信息加密方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Java+OpenCV实现人脸检测并自动拍照

    Java+OpenCV实现人脸检测并自动拍照

    这篇文章主要为大家详细介绍了Java+OpenCV实现人脸检测,并调用笔记本摄像头实时抓拍,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07

最新评论