> 文档中心 > 超详细带你用Java实现QQ的聊天功能

超详细带你用Java实现QQ的聊天功能

超详细带你用Java实现QQ的聊天功能

在这里插入图片描述

个人名片:

🐼作者简介:一名在校生
🐻‍❄️个人主页:hmm.
🕊️系列专栏:零基础学java ----- 重识c语言
🐓每日一句:只要还有明天,今天就永远是起跑点。

文章目录

  • 第一步:完成界面搭建🐓
  • 第二步:TPC通信的思路与步骤🐻‍❄️
      • TCP协议🐶
    • TCP 服务端 具体步骤(客户端类似)🐮
      • TCP通信步骤代码实现:🐸
      • 点击发送按钮实现数据的传输🐺
    • 第三步:实现回车键发送数据(客户端类似)🐳
    • 全部代码:🐲

第一步:完成界面搭建🐓

超详细带你用Java实现QQ的聊天功能

要求:

  • 创建两个窗口:一个客户端,一个服务端,完成代码书写
    步骤:

1.定义JFrame窗体中的组件:文本域,滚动条,面板,文本框,按钮

 //属性    //文本域    private JTextArea jta;    //滚动条    private JScrollPane jsp;    //面板    private JPanel jp;    //文本框    private JTextField jtf;    //按钮    private JButton jb;
2.在构造方法中初始化窗口的组件:
 //构造方法    public ServerChatMain(){ //初始化组件 jta = new JTextArea(); //设置文本域默认不可编辑 jta.setEditable(false); //注意:需要将文本域添加到滚动条中,实现滚动效果 jsp =new JScrollPane(jta); //初始化面板 jp = new JPanel(); jtf = new JTextField(10); jb=new JButton("发送"); //注意:需要将文本框与按钮添加到面板中 jp.add(jtf); jp.add(jb);
  1. 注意:需要将滚动条与面板全部添加到窗体中,继承了窗体的属性,这里this就是窗体
 this.add(jsp, BorderLayout.CENTER);//BorderLayout--边框布局 this.add(jp,BorderLayout.SOUTH);

4.设置设置”标题“,大小,位置,关闭,是否可见

   //注意:需要设置”标题“,大小,位置,关闭,是否可见 this.setTitle("QQ聊天服务端"); this.setSize(400,300); this.setLocation(700,300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭,程序就退出 this.setVisible(true);//设置窗体可见    }

这样我们就完成了服务端的QQ聊天界面窗口搭建:
注意:JTextArea文本域是不可以书写的
超详细带你用Java实现QQ的聊天功能
客户端与服务端代码类似,这里就不一一展示了

书写完毕代码,运行效果如下图:

超详细带你用Java实现QQ的聊天功能


超详细带你用Java实现QQ的聊天功能

第二步:TPC通信的思路与步骤🐻‍❄️

使用网络编程完成数据点的传输(TCP,UDP协议)

TCP协议🐶

TCP 是面向连接的运输层协议。应用程序在使用 TCP 协议之前,必须先建立 TCP 连接。在传送数据完毕后,必须释放已经建立的 TCP 连接
每一条 TCP 连接只能有两个端点,每一条 TCP 连接只能是点对点的(一对一)
TCP 提供可靠交付的服务。通过 TCP 连接传送的数据,无差错、不丢失、不重复,并且按序到达
TCP 提供全双工通信。TCP 允许通信双方的应用进程在任何时候都能发送数据。TCP 连接的两端都设有发送缓存和接受缓存,用来临时存放双向通信的数据
面向字节流。TCP 中的“流”指的是流入到进程或从进程流出的字节序列
超详细带你用Java实现QQ的聊天功能
超详细带你用Java实现QQ的聊天功能

TCP 服务端 具体步骤(客户端类似)🐮

具体步骤:

  •    1.创建一个服务端的套接字
  •     2.等待客户端连接
  •    3.获取socket通道的输入流(输入六是实现读取数据的,一行一行读取)BufferedReader->readLine();
  •     4.获取socket 通道的输出流(输出流实现写出数据,也是写一行换一行,刷新)BufferedWriter->newLine();
  •     5.关闭socket 通道

TCP通信步骤代码实现:🐸

 try {     //1.创建一个服务端的套接字     ServerSocket serverSocket = new ServerSocket(8888);     //2.等待客户端连接    Socket socket = serverSocket.accept();     //3.获取socket通道的输入流(输入六是实现读取数据的,一行一行读取)BufferedReader->readLine();     //InputStream in = socket.getInputStream();    BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));     //4.获取socket 通道的输出流(输出流实现写出数据,也是写一行换一行,刷新)BufferedWriter->newLine();     //当用户点击发送按钮的时候写出数据     BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));     //循环读取数据并拼接到文本域     String line = null;    while((line = br.readLine())!=null){ //将读取的数据拼接到文本域中显示 jta.append(line+System.lineSeparator());    }     //5.关闭socket 通道     serverSocket.close(); }catch (IOException e) {     e.printStackTrace(); }

点击发送按钮实现数据的传输🐺

 @Override    public void actionPerformed(ActionEvent actionEvent) { System.out.println("发送按钮被点击了");    }

步骤:

1.获取文本框中发送的内容
2.拼接需要发送的数据内容
3.自己也要显示
4.发送
5.清空文本框内容

@Override    public void actionPerformed(ActionEvent actionEvent) { //System.out.println("发送按钮被点击了"); //1.获取文本框中发送的内容 String text = jtf.getText(); //2.拼接需要发送的数据内容 text = "服务端对客户端说:"+text; //3.自己也要显示 jta.append(text); //4.发送 try {     bw.write(text);     bw.newLine();//换行刷新     bw.flush();     //5.清空文本框内容     jtf.setText(""); } catch (IOException e) {     e.printStackTrace(); }    }

在这里插入图片描述

第三步:实现回车键发送数据(客户端类似)🐳

首先要实现一个接口

public class ClientChatMain extends JFrame implements ActionListener, KeyListener {
@Override    public void keyPressed(KeyEvent e) { //回车键 // System.out.println(e); //发送数据到socket 同道中 if(e.getKeyCode()==KeyEvent.VK_ENTER) { sendDataToSocket();    }

在这里插入图片描述

全部代码:🐲

服务端:

package com.ithmm.chat;import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.io.*;import java.net.ServerSocket;import java.net.Socket;import java.util.Properties;//说明:如果一个类,需要有界面的显示,那么这个类就需要继承JFrame,此时,该类可以被成为一个窗体类/*步骤:     1.定义JFrame窗体中的组件     2.在构造方法中初始化窗口的组件     3.使用网络编程完成数据的链接(TPC,UDP  协议)     4.实现"发送”按钮的监听点击事件     5.实现“回车键”发送数据 */public class ServerChatMain extends JFrame implements ActionListener, KeyListener {    public static void main(String[] args) { //调用构造方法 new ServerChatMain();    }    //属性    //文本域    private JTextArea jta;    //滚动条    private JScrollPane jsp;    //面板    private JPanel jp;    //文本框    private JTextField jtf;    //按钮    private JButton jb;    //输出流(成员变量)    private BufferedWriter bw = null;    //服务端的端口号    //private static int serverPort;    //使用static静态方法读取外部京台文件    //static代码块特点:1.在类加载的时候自动执行    //特点2:一个类会被加载一次,因此静态代码块在程序中仅会被执行一次    /*static{ Properties prop = new Properties(); try {     //加载     prop.load(new FileReader("chat.properties"));     //给属性赋值     Integer.parseInt(prop.getProperty("serverPort")); } catch (IOException e) {     e.printStackTrace(); }    }*/    //构造方法    public ServerChatMain(){ //初始化组件 jta = new JTextArea(); //设置文本域默认不可编辑 jta.setEditable(false); //注意:需要将文本域添加到滚动条中,实现滚动效果 jsp =new JScrollPane(jta); //初始化面板 jp = new JPanel(); jtf = new JTextField(10); jb=new JButton("发送"); //注意:需要将文本框与按钮添加到面板中 jp.add(jtf); jp.add(jb); //注意:需要将滚动条与面板全部添加到窗体中,继承了窗体的属性,这里this就是窗体 this.add(jsp, BorderLayout.CENTER);//BorderLayout--边框布局 this.add(jp,BorderLayout.SOUTH); //注意:需要设置”标题“,大小,位置,关闭,是否可见 this.setTitle("QQ聊天服务端"); this.setSize(400,300); this.setLocation(700,300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭,程序就退出 this.setVisible(true);//设置窗体可见 /**************** TCP   服务端    Start *********************/ //给发送按钮绑定一个监听点击事件 jb.addActionListener(this); //给文本框绑定一个键盘点击事件 jtf.addKeyListener(this); try {     //1.创建一个服务端的套接字     ServerSocket serverSocket = new ServerSocket(8888);     //2.等待客户端连接    Socket socket = serverSocket.accept();     //3.获取socket通道的输入流(输入六是实现读取数据的,一行一行读取)BufferedReader->readLine();     //InputStream in = socket.getInputStream();    BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));     //4.获取socket 通道的输出流(输出流实现写出数据,也是写一行换一行,刷新)BufferedWriter->newLine();     //当用户点击发送按钮的时候写出数据     bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));     //循环读取数据并拼接到文本域     String line = null;    while((line = br.readLine())!=null){ //将读取的数据拼接到文本域中显示 jta.append(line+System.lineSeparator());    }     //5.关闭socket 通道     serverSocket.close(); }catch (IOException e) {     e.printStackTrace(); } /**************** TCP   服务端    end  *********************/    }    @Override    public void actionPerformed(ActionEvent actionEvent) { //System.out.println("发送按钮被点击了");sendDataToSocket();    }    //行为    @Override    public void keyPressed(KeyEvent e) { //回车键 // System.out.println(e); //发送数据到socket 同道中 if(e.getKeyCode()==KeyEvent.VK_ENTER) {     sendDataToSocket(); }    }    //定义一个方法,实现将数据发送到socket通道中    private void sendDataToSocket(){ //1.获取文本框中发送的内容 String text = jtf.getText(); //2.拼接需要发送的数据内容 text = "服务端对客户端说:"+text; //3.自己也要显示 jta.append(text+System.lineSeparator()); //4.发送 try {     bw.write(text);     bw.newLine();//换行刷新     bw.flush();     //5.清空文本框内容     jtf.setText(""); } catch (IOException e) {     e.printStackTrace(); }    }    @Override    public void keyTyped(KeyEvent keyEvent) {    }    @Override    public void keyReleased(KeyEvent keyEvent) {    }}

客户端:

import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;import java.awt.BorderLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.Socket;import java.util.Properties;//说明:如果一个类,需要有界面的显示,那么这个类就需要继承JFrame,此时,该类可以被成为一个窗体类/*步骤:     1.定义JFrame窗体中的组件     2.在构造方法中初始化窗口的组件 */public class ClientChatMain extends JFrame implements ActionListener, KeyListener {    public static void main(String[] args) { //调用构造方法 new ClientChatMain();    }    //属性    //文本域    private JTextArea jta;    //滚动条    private JScrollPane jsp;    //面板    private JPanel jp;    //文本框    private JTextField jtf;    //按钮    private JButton jb;    //s输出流    private BufferedWriter bw =null;    //客户端的IP地址   // private static String clientIp;    //客户端的port端口号   // private static int clientPort;    //静态代码块加载外部配置文件   /* static{      Properties prop = new Properties(); try {     prop.load(new FileReader("chat.properties"));     clientIp = prop.getProperty("clientIp");     clientPort =Integer.parseInt( prop.getProperty("clientPort")); } catch (IOException e) {     e.printStackTrace(); }    }*/    //构造方法    public ClientChatMain(){ //初始化组件 jta = new JTextArea(); //设置文本域默认不可编辑 jta.setEditable(false); //注意:需要将文本域添加到滚动条中,实现滚动效果 jsp =new JScrollPane(jta); //初始化面板 jp = new JPanel(); jtf = new JTextField(10); jb=new JButton("发送"); //注意:需要将文本框与按钮添加到面板中 jp.add(jtf); jp.add(jb); //注意:需要将滚动条与面板全部添加到窗体中,继承了窗体的属性,这里this就是窗体 this.add(jsp, BorderLayout.CENTER);//BorderLayout--边框布局 this.add(jp,BorderLayout.SOUTH); //注意:需要设置”标题“,大小,位置,关闭,是否可见 this.setTitle("QQ聊天客户端"); this.setSize(400,300); this.setLocation(700,300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭,程序就退出 this.setVisible(true);//设置窗体可见 /**************** TCP   客户端    Start *********************/ //给发送按钮绑定一个监听点击事件 jb.addActionListener(this); //给文本框绑定一个键盘键 jtf.addKeyListener(this); try {     //1.创建一个客户端的套接字(尝试连接)     Socket socket = new Socket("127.0.0.1",8888);     //2.获取socket通道的输入流    BufferedReader br =  new BufferedReader(new InputStreamReader(socket.getInputStream()));     //3.获取socket 通道的输出流   bw =  new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));     //循环读取数据,并拼接到文本域    String line = null;    while((line = br.readLine())!=null){ jta.append(line + System.lineSeparator());    }     //4.关闭socket 通道     socket.close(); }catch (Exception e){     e.printStackTrace(); } /**************** TCP   客户端    end  *********************/    }    @Override    public void actionPerformed(ActionEvent e) {sendDataToSocket();    }    //行为    @Override    public void keyPressed(KeyEvent e) { //回车键 if(e.getKeyCode() == KeyEvent.VK_ENTER){     //发送数据     sendDataToSocket(); }    }    private void sendDataToSocket(){ //1.获取文本框需要发送内容 String text = jtf.getText(); //2.拼接内容 text = "客户端对服务端说"+text; //3.自己显示 jta.append(text+System.lineSeparator()); try {     //4.发送     bw.write(text);     bw.newLine();//换行加刷新     bw.flush();     bw.write(text);     //5.清空     jtf.setText(""); } catch (IOException e) {     e.printStackTrace(); }    }    @Override    public void keyTyped(KeyEvent e) {    }    @Override    public void keyReleased(KeyEvent e) {    }}

接口类:

public interface addActistener {}
public interface addActionListener {}

在这里插入图片描述
兄弟们,三连支持一下!!!

开发者涨薪指南 超详细带你用Java实现QQ的聊天功能 48位大咖的思考法则、工作方式、逻辑体系局座张召忠