个人名片:
🐼作者简介:一名在校生
🐻❄️个人主页:hmm.
🕊️系列专栏:零基础学java ----- 重识c语言
🐓每日一句:只要还有明天,今天就永远是起跑点。
要求:
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);
-
- 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文本域是不可以书写的
客户端与服务端代码类似,这里就不一一展示了
书写完毕代码,运行效果如下图:
使用网络编程完成数据点的传输(TCP,UDP协议)
TCP 是面向连接的运输层协议。应用程序在使用 TCP 协议之前,必须先建立 TCP 连接。在传送数据完毕后,必须释放已经建立的 TCP 连接
每一条 TCP 连接只能有两个端点,每一条 TCP 连接只能是点对点的(一对一)
TCP 提供可靠交付的服务。通过 TCP 连接传送的数据,无差错、不丢失、不重复,并且按序到达
TCP 提供全双工通信。TCP 允许通信双方的应用进程在任何时候都能发送数据。TCP 连接的两端都设有发送缓存和接受缓存,用来临时存放双向通信的数据
面向字节流。TCP 中的“流”指的是流入到进程或从进程流出的字节序列
具体步骤:
1.创建一个服务端的套接字
2.等待客户端连接
3.获取socket通道的输入流(输入六是实现读取数据的,一行一行读取)BufferedReader->readLine();
4.获取socket 通道的输出流(输出流实现写出数据,也是写一行换一行,刷新)BufferedWriter->newLine();
5.关闭socket 通道
- 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 {
- }
兄弟们,三连支持一下!!!