资讯详情

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

38051ee198e84322bd29f5d555caaf31.png

??作者简介:一名学生 ???个人主页:hmm. ???系列专栏:零基础学java ----- 重识c语言 ??每日一句话:只要还有明天,今天就永远是起点。


???

**</font> >***???? >**???

文章目录

  • 第一步:完成界面构建
  • 第二步:TPC通信的思路和步骤
      • TCP协议??
    • TCP 服务端 具体步骤(类似客户端)
      • TCP实现通信步骤代码:
      • 点击发送按钮实现数据传输
    • 第三步:实现回车键发送数据(类似客户端)
    • 全部代码:??

第一步:完成界面构建

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

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文本域不能写。 客户端类似于服务端代码,这里就不一一展示了

编写代码后,操作效果如下图所示:


第二步:TPC通信的思路和步骤

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

TCP协议??

TCP 是面向连接的运输层协议。使用应用程序 TCP 在协议建立之前 TCP 连接。传输数据后,必须释放已建立的数据 TCP 连接 每一条 TCP 连接只能有两个端点,每个端点 TCP 连接只能是点对点(一对一) TCP 提供可靠交付的服务。通过 TCP 连接传输的数据,无错误,无丢失,无重复,并按顺序到达 TCP 提供全双工通信。TCP 允许通信双方的应用程序随时发送数据。TCP 发送缓存和接收缓存用于临时存储双向通信的数据 面向字节流。TCP 流是指流入过程或流出过程的字节序列

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

  •    1.创建服务端的套接字 
  •     2.等待客户端连接 
  •    3.获取socket输入流(输入6是读取数据,一行一行读取)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 {
}

兄弟们,三连支持一下!!!

标签: bw氯气传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台