0


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

在这里插入图片描述

在这里插入图片描述

个人名片:

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

文章目录

第一步:完成界面搭建🐓

QQ聊天框界面

要求:

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

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

//属性//文本域privateJTextArea jta;//滚动条privateJScrollPane jsp;//面板privateJPanel jp;//文本框privateJTextField jtf;//按钮privateJButton jb;
2.在构造方法中初始化窗口的组件:
//构造方法publicServerChatMain(){//初始化组件
        jta =newJTextArea();//设置文本域默认不可编辑
        jta.setEditable(false);//注意:需要将文本域添加到滚动条中,实现滚动效果
        jsp =newJScrollPane(jta);//初始化面板
        jp =newJPanel();
        jtf =newJTextField(10);
        jb=newJButton("发送");//注意:需要将文本框与按钮添加到面板中
        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文本域是不可以书写的
QQ服务端
客户端与服务端代码类似,这里就不一一展示了

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

在这里插入图片描述


在这里插入图片描述

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

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

TCP协议🐶

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

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

具体步骤:

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

TCP通信步骤代码实现:🐸

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

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

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

步骤:

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

@OverridepublicvoidactionPerformed(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();}}

在这里插入图片描述

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

首先要实现一个接口

publicclassClientChatMainextendsJFrameimplementsActionListener,KeyListener{
@OverridepublicvoidkeyPressed(KeyEvent e){//回车键// System.out.println(e);//发送数据到socket 同道中if(e.getKeyCode()==KeyEvent.VK_ENTER){sendDataToSocket();}

在这里插入图片描述

全部代码:🐲

服务端:

packagecom.ithmm.chat;importjavax.swing.*;importjava.awt.*;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener;importjava.io.*;importjava.net.ServerSocket;importjava.net.Socket;importjava.util.Properties;//说明:如果一个类,需要有界面的显示,那么这个类就需要继承JFrame,此时,该类可以被成为一个窗体类/*步骤:
     1.定义JFrame窗体中的组件
     2.在构造方法中初始化窗口的组件
     3.使用网络编程完成数据的链接(TPC,UDP  协议)
     4.实现"发送”按钮的监听点击事件
     5.实现“回车键”发送数据
 */publicclassServerChatMainextendsJFrameimplementsActionListener,KeyListener{publicstaticvoidmain(String[] args){//调用构造方法newServerChatMain();}//属性//文本域privateJTextArea jta;//滚动条privateJScrollPane jsp;//面板privateJPanel jp;//文本框privateJTextField jtf;//按钮privateJButton jb;//输出流(成员变量)privateBufferedWriter 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();
        }
    }*///构造方法publicServerChatMain(){//初始化组件
        jta =newJTextArea();//设置文本域默认不可编辑
        jta.setEditable(false);//注意:需要将文本域添加到滚动条中,实现滚动效果
        jsp =newJScrollPane(jta);//初始化面板
        jp =newJPanel();
        jtf =newJTextField(10);
        jb=newJButton("发送");//注意:需要将文本框与按钮添加到面板中
        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 =newServerSocket(8888);//2.等待客户端连接Socket socket = serverSocket.accept();//3.获取socket通道的输入流(输入六是实现读取数据的,一行一行读取)BufferedReader->readLine();//InputStream in = socket.getInputStream();BufferedReader br=newBufferedReader(newInputStreamReader(socket.getInputStream()));//4.获取socket 通道的输出流(输出流实现写出数据,也是写一行换一行,刷新)BufferedWriter->newLine();//当用户点击发送按钮的时候写出数据
            bw =newBufferedWriter(newOutputStreamWriter(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  *********************/}@OverridepublicvoidactionPerformed(ActionEvent actionEvent){//System.out.println("发送按钮被点击了");sendDataToSocket();}//行为@OverridepublicvoidkeyPressed(KeyEvent e){//回车键// System.out.println(e);//发送数据到socket 同道中if(e.getKeyCode()==KeyEvent.VK_ENTER){sendDataToSocket();}}//定义一个方法,实现将数据发送到socket通道中privatevoidsendDataToSocket(){//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();}}@OverridepublicvoidkeyTyped(KeyEvent keyEvent){}@OverridepublicvoidkeyReleased(KeyEvent keyEvent){}}

客户端:

importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JPanel;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;importjava.awt.BorderLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener;importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.OutputStreamWriter;importjava.net.Socket;importjava.util.Properties;//说明:如果一个类,需要有界面的显示,那么这个类就需要继承JFrame,此时,该类可以被成为一个窗体类/*步骤:
     1.定义JFrame窗体中的组件
     2.在构造方法中初始化窗口的组件
 */publicclassClientChatMainextendsJFrameimplementsActionListener,KeyListener{publicstaticvoidmain(String[] args){//调用构造方法newClientChatMain();}//属性//文本域privateJTextArea jta;//滚动条privateJScrollPane jsp;//面板privateJPanel jp;//文本框privateJTextField jtf;//按钮privateJButton jb;//s输出流privateBufferedWriter 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();
        }
    }*///构造方法publicClientChatMain(){//初始化组件
        jta =newJTextArea();//设置文本域默认不可编辑
        jta.setEditable(false);//注意:需要将文本域添加到滚动条中,实现滚动效果
        jsp =newJScrollPane(jta);//初始化面板
        jp =newJPanel();
        jtf =newJTextField(10);
        jb=newJButton("发送");//注意:需要将文本框与按钮添加到面板中
        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 =newSocket("127.0.0.1",8888);//2.获取socket通道的输入流BufferedReader br =newBufferedReader(newInputStreamReader(socket.getInputStream()));//3.获取socket 通道的输出流
          bw =newBufferedWriter(newOutputStreamWriter(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  *********************/}@OverridepublicvoidactionPerformed(ActionEvent e){sendDataToSocket();}//行为@OverridepublicvoidkeyPressed(KeyEvent e){//回车键if(e.getKeyCode()==KeyEvent.VK_ENTER){//发送数据sendDataToSocket();}}privatevoidsendDataToSocket(){//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();}}@OverridepublicvoidkeyTyped(KeyEvent e){}@OverridepublicvoidkeyReleased(KeyEvent e){}}

接口类:

publicinterface addActistener {}
publicinterface addActionListener {}

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

标签: java 开发语言 idea

本文转载自: https://blog.csdn.net/m0_68089732/article/details/124897209
版权归原作者 hmm️. 所有, 如有侵权,请联系我们删除。

“超详细带你用Java实现QQ的聊天功能”的评论:

还没有评论