Java实验三 基于GUI的网络通信程序设计【代码构建逻辑】【双向通信】【超多细节优化!!】

2023-11-18

写在前面:这次实验代码的构建主要是更加熟练的运用socket网络编程、文件输入输出流、GUI设计、容器的使用、多线程的运用等等多方面的知识,是综合类题型,做完受益身心的类型。

题目如下:

编写程序完成以下功能:

1.设计一个基于GUI的客户-服务器的通信应用程序,如图1,图2所示。

图1 Socket通信服务器端界面

图2 Socket通信客户端界面

2.图1为Socket通信服务器端界面,点击该界面中的【Start】按钮,启动服务器监听服务(在图1界面中间的多行文本区域显示“Server starting…”字样)。图2为Socket通信客户端界面,点击该界面中的【Connect】按钮与服务器建立链接,并在图2所示界面中间的多行文本区域显“Connect to server…”字样,当服务器端监听到客户端的连接后,在图1界面中间的多行文本区域追加一行“Client connected…”字样,并与客户端建立Socket连接。

3.当图1所示的服务器端和图2所示的客户机端建立Socket连接后,编程实现服务端、客户端之间的“单向通信”:在客户端的输入界面发送消息,在服务端接收该消息,并将接收到对方的数据追加显示在多行文本框中。


 下面开始做题:

一、学习基础知识

(如果想要学到什么的话,可以根据清单去学,不花很多时间

首先主要需要了解socket的知识,包括但不限于下列:(以下为最主要、基础的知识

1. ServerSocket、Socket的构造函数,需要什么东西来构造

2. 了解服务器与客户端之间依靠中间Socket连接,获取输入输出流

3. 为什么需要多线程,以及多线程的两种基本操作方法

        1) implements Runnable 

        2) extends Thread 

4. 在服务器与客户端通信的过程中,会引起阻塞的操作有哪几种。

了解完一些基本知识,发车,冲!!~

二、代码逻辑构建与代码包细节

之后,做出如下代码构建逻辑  (无GUI版 先设计这版的更容易理解基础知识。

 然后用如下代码包体现上面的逻辑构建

(无GUI版) 具体代码如下:(很多很多,我自己都不爱看  不过也不需要看,毕竟是我写的 :) 但是看一遍逻辑会清楚很多

因为比较大,所以分开服务端、客户端截图。

只是看起来很复杂,因为具体代码怎么写的都基本写出来,所以会显得很多。

 


但是毕竟我们的作业是有GUI版,所以再次进行代码逻辑构建

(有了上面一版的理解,有GUI版仅仅是多了GUI的代码设计而已

 

 上图知识点解释来啦:

1. 因为代码为了区分功能开了很多的类和文件 所以main函数主要用来组织这些类的发生。

2. 输出不需要等待scanner类的键盘输入了,只需要判断文本框内有没有东西然后直接输出就行,然后就直接send就可以了。

3. 因为服务器的启动时间由start组件来监听开启,所以相比于无GUI版代码直接使用start组件的类兼职accept(),意思是服务器默认永久等待客户端连接。

4. 和3一样,connect类相当于客户端的main函数,而且因为输出仅仅需要send来等待,所以这个时候使用connect兼职一下监听。

5. 为什么start和connect的里面的actionperformed不可以直接进行accept和监听呢?

因为在actionPerformed中体现点击事件,如果actionPerformed过长会一直假卡死,即该UI界面无法发生其他事件,无法进入下个动作,所以类似于accept和监听这样长时间的会阻塞线程的动作我们单独开启一个工作线程就不放在actionperformed里面了。

 代码包以及代码作用如下:(可以放大查看,代码思路都交代了

  注意:本来这里可以不使用接口类,其实没有必要,但是当时自己想实践一下面向接口的思想,并且让代码更有逻辑有利于后期维护,所以采用了很多接口类。

其实如果为了让actionperformed函数分开功能的话只需要直接写一个类进行了。不需要再写接口了。


有GUI版代码相比于无GUI版改进了很多用户交互的内容,做了很多优化包括但不限于:

1. 双向通信 2.选择不同客户发送消息 3.按钮事件的控制以及很多事件源监视器的委派 4.默认本地服务器等等。

三、具体成果显示

1. 可以连接多个客户

细节的优化:按钮事件的控制,不可调整窗口大小,默认本机地址、不同客户有自己的名字、且存在于下拉菜单中等等

2. 双向通信

细节的优化:区分客户发送的消息、分别发送给不同客户、 按钮点击文本框的清空等等

 

 3. 客户断开连接


附完整可运行代码:

代码逻辑如图: 

C_MyCommandSurveillanceForConnect接口
package Client;

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

public interface C_MyCommandSurveillanceForConnect extends ActionListener {
     void setJTextField_IP(JTextField jTextField);
     void setJTextField_Port(JTextField jTextField);
     void setJTextArea(JTextArea jTextArea);
     void setSocket(Socket socket);
     void setBtn(JButton jButton);
}

C_MyCommandSurveillanceForSend接口
package Client;

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

public interface C_MyCommandSurveillanceForSend extends ActionListener {
    void setJTextField(JTextField jTextField);
    void setSocket(Socket socket);
}

C_MySurveillanceForConnect类
package Client;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;


//根据输入的IP地址与端口号进行连接、监听信息线程 Client、ClientListen
public class C_MySurveillanceForConnect extends Thread implements C_MyCommandSurveillanceForConnect{
    JTextField jTextField_IP;
    JTextField jTextField_Port;
    JTextArea jTextArea;
    JButton btn;
    Socket client;
    DataInputStream in;
    String str;
    public void setJTextField_IP(JTextField jTextField){
        this.jTextField_IP = jTextField;
    }
    public void setJTextField_Port(JTextField jTextField){
        this.jTextField_Port = jTextField;
    }
    public void setBtn(JButton jButton){
        this.btn = jButton;
    }
    public void setJTextArea(JTextArea jTextArea){
        this.jTextArea = jTextArea;
    }
    public void setSocket(Socket socket){
        this.client = socket;
    }

    public void actionPerformed(ActionEvent e){
        btn.setEnabled(false);
        //判断IP与Port都填写完整,进行连接
        String IP, Port;
        if((Port = jTextField_Port.getText()) != null){
            InetAddress address;
            //开始进行连接
            try {
                if((IP = jTextField_IP.getText()) == null){
                    address = InetAddress.getLocalHost();
                }
                else{
                    address = InetAddress.getByName(IP);
                }
            }
            catch (UnknownHostException ex) {
                throw new RuntimeException(ex);
            }
            InetSocketAddress socketAddress = new InetSocketAddress(address, Integer.parseInt(Port));

            try {
                client.connect(socketAddress);
                jTextArea.append("Connecting to server...\n");
                jTextArea.paintImmediately(jTextArea.getBounds());
                in = new DataInputStream(client.getInputStream());

                Thread thread = this;
                thread.start();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }

        }
        else{
            jTextArea.append("Please enter right IP and Port...\n");
            jTextArea.paintImmediately(jTextArea.getBounds());
        }

    }
    public void run(){

        while(true){
            try {
                str = in.readUTF();
                jTextArea.append("From server: " + str + "\n");
            } catch (IOException ex) {
                jTextArea.append("Disconnected to server...");
                jTextArea.paintImmediately(jTextArea.getBounds());
                break;
            }
        }
    }
}

C_MySurveillanceForSend类
package Client;

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

//发送信息  ClientTx

public class C_MySurveillanceForSend implements C_MyCommandSurveillanceForSend {
    JTextField jTextField;
    Socket client;
    DataOutputStream out;

    public void setJTextField(JTextField jTextField){
        this.jTextField = jTextField;
    }
    public void setSocket(Socket socket){
        this.client = socket;
    }

    public void actionPerformed(ActionEvent e){
        try {
            out = new DataOutputStream(client.getOutputStream());
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
        try {
            out.writeUTF(jTextField.getText());
            jTextField.setText(null);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }
}
C_MyGUI类
package Client;

import javax.swing.*;
import java.awt.*;
import java.net.Socket;

import static java.awt.Font.ITALIC;


//设置页面 添加监视器
public class C_MyGUI extends JFrame {
    JFrame jFrame = new JFrame();
    JTextField textF_IP, textF_port, textF_send;
    JButton btn_Connect, btn_send;
    JTextArea textArea;
    JPanel jPanel01;
    JPanel jPanel02;
    JPanel jPanel03;
    JPanel jPanel;
    //监视器接口
    C_MyCommandSurveillanceForSend myCommandSurveillanceForSend;
    C_MyCommandSurveillanceForConnect myCommandSurveillanceForConnect;
    //一个对象
    Socket client;

    //构造函数完成窗口的主流操作
    public C_MyGUI(){
        client = new Socket();
        init();
        jFrame.setResizable(false);
        jFrame.setBounds(100,100,460,360);
        jFrame.setTitle("客户端");
        jFrame.setVisible(true);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    void init(){
        //服务器设置框
        jPanel = new JPanel();
        jPanel01 = new JPanel();
        jPanel02 = new JPanel();
        jPanel03 = new JPanel();
        textF_IP = new JTextField(10);
        textF_IP.setFont(new Font(null, Font.BOLD, 13));
        textF_port = new JTextField(8);
        textF_port.setFont(new Font(null, Font.BOLD, 13));
        btn_Connect = new JButton("Connect");
        jPanel01.add(new JLabel("Server IP: "));
        jPanel01.add(textF_IP);
        jPanel01.add(new JLabel("Port: "));
        jPanel01.add(textF_port);
        jPanel01.add(btn_Connect);
        jPanel01.setBorder(BorderFactory.createTitledBorder("客户机设置:"));
        //中间文本框
        textArea = new JTextArea(9,30);
        textArea.setLineWrap(true);
        textArea.setFont(new Font(null, Font.BOLD+ITALIC, 15));
        JScrollPane jScrollPane = new JScrollPane();
        jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        jScrollPane.setViewportView(textArea);
        jPanel02.add(jScrollPane);
        //send发送信息栏
        textF_send = new JTextField(23);
        textF_send.setFont(new Font(null, Font.BOLD, 13));
        btn_send = new JButton("Send");
        jPanel03.add(new JLabel("Send: "));
        jPanel03.add(textF_send);
        jPanel03.add(btn_send);

        //将上中下三个组件存放如jPanel
        jPanel.add(jPanel01,BorderLayout.NORTH);
        jPanel.add(jPanel02,BorderLayout.CENTER);
        jPanel.add(jPanel03,BorderLayout.SOUTH);
        jFrame.setContentPane(jPanel);
    }

    //设置监视器
    void setMyCommandSurveillanceForConnect(C_MyCommandSurveillanceForConnect myCommandSurveillanceForConnect){
        //利用组合设置对象
        this.myCommandSurveillanceForConnect = myCommandSurveillanceForConnect;
        myCommandSurveillanceForConnect.setJTextField_Port(textF_port);
        myCommandSurveillanceForConnect.setJTextField_IP(textF_IP);
        myCommandSurveillanceForConnect.setJTextArea(textArea);
        myCommandSurveillanceForConnect.setSocket(client);
        myCommandSurveillanceForConnect.setBtn(btn_Connect);
        //为事件源添加监视器  用户点击按钮才能够触发事件
        textF_port.addActionListener(myCommandSurveillanceForConnect);
        textF_IP.addActionListener(myCommandSurveillanceForConnect);
        btn_Connect.addActionListener(myCommandSurveillanceForConnect);
    }
    void setMyCommandSurveillanceForSend(C_MyCommandSurveillanceForSend myCommandSurveillanceForSend){
        this.myCommandSurveillanceForSend = myCommandSurveillanceForSend;
        myCommandSurveillanceForSend.setJTextField(textF_send);
        myCommandSurveillanceForSend.setSocket(client);
        //为事件源添加监视器
        textF_send.addActionListener(myCommandSurveillanceForSend);
        btn_send.addActionListener(myCommandSurveillanceForSend);
    }


}
Client_main类(可以设置多个相同的main类想起来连接了多个客户
package Client;


//192.168.197.121


public class Client_main {
    public static void main(String[] args){
        //设置GUI界面
        C_MyGUI myGui = new C_MyGUI();
        //设置监视器
        C_MySurveillanceForConnect MySurveillanceForConnect = new C_MySurveillanceForConnect();
        C_MySurveillanceForSend mySurveillanceForSend = new C_MySurveillanceForSend();
        myGui.setMyCommandSurveillanceForConnect(MySurveillanceForConnect);
        myGui.setMyCommandSurveillanceForSend(mySurveillanceForSend);

    }
}

S_MyCommandSurveillanceForStart接口
package Server;

import javax.swing.*;
import java.awt.event.ActionListener;

public interface S_MyCommandSurveillanceForStart extends ActionListener {
    void setJTextField(JTextField jTextField);
    void setJTextArea(JTextArea jTextArea);
    void setJBtn(JButton jButton);

}

S_MyCommandSurveillanceForSend接口
package Server;

import javax.swing.*;
import java.awt.event.ActionListener;

public interface S_MyCommandSurveillanceForSend extends ActionListener {
     void setJTextField(JTextField jTextField);
     void setJComboBox(JComboBox<String> jComboBox);
}

S_MySurveillanceForStart类
package Server;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Objects;

import static Server.S_MyGUI.socket_name;
import static Server.S_MyGUI.scs;


//accept工作线程 作用:基于GUI,读取port框内内容进行连接操作
//为客户取名,并且为每一位用户开启监听线程

public class S_MySurveillanceForStart extends Thread implements S_MyCommandSurveillanceForStart{
    JTextField Port;
    JTextArea jTextArea;
    JButton jButton;
    ServerSocket serverSocket;
    Socket sc;
    String client = "Client";
    String Client_name = null;
    static int client_num = 1;
    public void setJTextField(JTextField jTextField){
        this.Port = jTextField;
    }
    public void setJTextArea(JTextArea TextArea){
        this.jTextArea = TextArea;
    }
    public void setJBtn(JButton jButton){ this.jButton = jButton;}

    public void actionPerformed(ActionEvent e){
        Thread thread = this;
        thread.start();
    }
    public void run(){
        while(true){
            try{
                if(Port.getText() != null){
                    serverSocket = new ServerSocket(Integer.parseInt(Port.getText()));
                }
                else{
                    jTextArea.append("Please enter right Port...");
                    jTextArea.paintImmediately(jTextArea.getBounds());
                    break;
                }
            }
            catch (IOException exception){
                jTextArea.append("Server listening..."+ "\n");
                jTextArea.paintImmediately(jTextArea.getBounds());
            }
            try {
                if(client_num == 1){
                    jTextArea.append("Server starting..."+ "\n");
                    jTextArea.paintImmediately(jTextArea.getBounds());
                }
                sc = serverSocket.accept();
                scs.add(sc);
                if(Objects.equals(socket_name.get(0), "null")){
                    socket_name.remove(0);
                }
                Client_name = client + client_num;
                jTextArea.append(Client_name+" connected..."+ "\n");
                socket_name.add(Client_name);
                jTextArea.paintImmediately(jTextArea.getBounds());
            } catch (IOException even) {
                jTextArea.append("Server waiting..."+ "\n");
                jTextArea.paintImmediately(jTextArea.getBounds());
            }
            if(sc != null){
                client_num++;
                new ServerListenThread(sc, jTextArea, Client_name).start();
            }
        }
    }

}

S_MySurveillanceForSend类
package Server;

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

import static Server.S_MyGUI.scs;

public class S_MySurveillanceForSend implements S_MyCommandSurveillanceForSend{

    JTextField jTextField;
    JComboBox<String> jComboBox;
    Socket sc;
    DataOutputStream out;

    public void setJTextField(JTextField jTextField){
        this.jTextField = jTextField;
    }
    public void setJComboBox(JComboBox<String> jComboBox){
        this.jComboBox = jComboBox;
    }

    public void actionPerformed(ActionEvent e){
        sc = scs.elementAt(jComboBox.getSelectedIndex());
        try {
            out = new DataOutputStream(sc.getOutputStream());
            out.writeUTF(jTextField.getText());
            jTextField.setText(null);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }

    }
}

S_MyGUI类
package Server;

import javax.swing.*;
import java.awt.*;
import java.net.Socket;
import java.util.Vector;
import static java.awt.Font.ITALIC;

//设置GUI界面 添加监视器 + 建立通信
public class S_MyGUI extends JFrame {
    //组件
    static Vector<String> socket_name;
    static Vector<Socket> scs;
    JFrame jFrame = new JFrame();
    JTextField textF_port, textF_send;
    JButton btn_start, btn_send;
    JTextArea textArea;
    JPanel jPanel01;
    JPanel jPanel02;
    JPanel jPanel03;
    JPanel jPanel;

    JComboBox<String> comboBox;
    //监视器接口
    S_MyCommandSurveillanceForStart myCommandSurveillanceForStart;
    S_MyCommandSurveillanceForSend myCommandSurveillanceForSend;
    //对象

    //构造函数完成窗口的主流操作
    public S_MyGUI(){
        socket_name = new Vector<>();
        scs = new Vector<>();
        socket_name.add("null");
        init();
        jFrame.setResizable(false);
        jFrame.setBounds(100,100,460,360);
        jFrame.setTitle("服务器");
        jFrame.setVisible(true);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    void init(){
        //服务器设置框
        jPanel = new JPanel();
        jPanel01 = new JPanel();
        jPanel02 = new JPanel();
        jPanel03 = new JPanel();
        textF_port = new JTextField(23);
        textF_port.setFont(new Font(null, Font.BOLD, 13));
        btn_start = new JButton("Start");
        jPanel01.add(new JLabel("Port: "));
        jPanel01.add(textF_port);
        jPanel01.add(btn_start);
        jPanel01.setBorder(BorderFactory.createTitledBorder("服务器设置:"));
        //中间文本框
        textArea = new JTextArea(9,30);
        textArea.setLineWrap(true);
        textArea.setFont(new Font(null, Font.BOLD+ITALIC, 15));
        JScrollPane jScrollPane = new JScrollPane();
        JScrollBar jscrollBar = jScrollPane.getVerticalScrollBar();
        if (jscrollBar != null) {
            // 必须先获取一次jScrollBar.getMaximum(),否则滚动不到最底部, swing bug
            jscrollBar.setValue(jscrollBar.getMaximum());
            jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        }
        jScrollPane.setViewportView(textArea);
        jPanel02.add(jScrollPane);
        //send发送信息栏
        textF_send = new JTextField(18);
        comboBox = new JComboBox<>(socket_name);
        textF_send.setFont(new Font(null, Font.BOLD, 13));
        btn_send = new JButton("Send");
        jPanel03.add(new JLabel("SendTo: "));
        jPanel03.add(comboBox);
        jPanel03.add(textF_send);
        jPanel03.add(btn_send);

        //将上中下三个组件存放如jPanel
        jPanel.add(jPanel01,BorderLayout.NORTH);
        jPanel.add(jPanel02,BorderLayout.CENTER);
        jPanel.add(jPanel03,BorderLayout.SOUTH);
        jFrame.setContentPane(jPanel);

    }

    //设置监视器
    void setMyCommandSurveillanceForStart(S_MyCommandSurveillanceForStart myCommandSurveillanceForStart){
        //利用组合设置对象
        this.myCommandSurveillanceForStart = myCommandSurveillanceForStart;
        myCommandSurveillanceForStart.setJTextField(textF_port);
        myCommandSurveillanceForStart.setJTextArea(textArea);
        myCommandSurveillanceForStart.setJBtn(btn_start);
        //为事件源添加监视器  用户按回车键、按钮都能够触发事件
        textF_port.addActionListener(myCommandSurveillanceForStart);
        btn_start.addActionListener(myCommandSurveillanceForStart);
    }
    void setMyCommandSurveillanceForSend(S_MyCommandSurveillanceForSend myCommandSurveillanceForSend){
        this.myCommandSurveillanceForSend = myCommandSurveillanceForSend;
        myCommandSurveillanceForSend.setJTextField(textF_send);
        myCommandSurveillanceForSend.setJComboBox(comboBox);
        //为事件源添加监视器
        textF_send.addActionListener(myCommandSurveillanceForSend);
        btn_send.addActionListener(myCommandSurveillanceForSend);

    }

}

ServerListenThread类
package Server;

import javax.swing.*;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import static Server.S_MyGUI.scs;
import static Server.S_MyGUI.socket_name;


//服务器输入流监听线程 作用:进行输入流的监听
public class ServerListenThread extends Thread{
    Socket sc;
    JTextArea jTextArea;
    DataInputStream in;
    String str;

    ServerListenThread(Socket socket, JTextArea jTextArea, String string){
        super(string);
        this.sc = socket;
        this.jTextArea = jTextArea;
        try {
            in = new DataInputStream(sc.getInputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //后台死循环进行监听
    public void run(){
        while(true){
            try {
                str = in.readUTF();
                jTextArea.append(getName() + ": " + str + "\n");
                jTextArea.paintImmediately(jTextArea.getBounds());
            } catch (IOException e) {
                int index = scs.indexOf(sc);
                jTextArea.append(socket_name.get(index) + "disconnected...\n");
                scs.remove(index);
                socket_name.remove(index);
                if(socket_name.isEmpty()){
                    socket_name.add("null");
                }
                break;
            }

        }
    }

}

Server_main类
package Server;




public class Server_main {
    public static void main(String[] args){
        //设置GUI界面
        S_MyGUI myGui = new S_MyGUI();
        //添加监视器,利用组合调用方法
        S_MySurveillanceForStart mySurveillanceForStart = new S_MySurveillanceForStart();
        S_MySurveillanceForSend mySurveillanceForSend = new S_MySurveillanceForSend();
        myGui.setMyCommandSurveillanceForStart(mySurveillanceForStart);
        myGui.setMyCommandSurveillanceForSend(mySurveillanceForSend);

    }
}

 至此,所有代码就完成了哈哈哈。

源代码和教程附上,说是教程其实主要是讲出构建整个代码的知识与思路,希望在完成作业的同时能够对你有帮助来学习思路。

如果觉得还不错的话...... :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java实验三 基于GUI的网络通信程序设计【代码构建逻辑】【双向通信】【超多细节优化!!】 的相关文章

  • Linux脚本练习之script092- 判断输入的是否为IP地址

    script092 题目 注 题目来源于 SHELL16 判断输入的是否为IP地址 写一个脚本统计文件nowcoder txt中的每一行是否是正确的IP地址 如果是正确的IP地址输出 yes 如果是错误的IP地址 四段号码的话输出 no 否
  • SpringBoot八种bean的加载方式

    目录 第一种bean的加载方式 配置文件 第二种加载bean方式 注解和扫描 创建第三方的bean对象 第三种加载bean方式 不使用配置文件 扩展 bean的加载方式扩展FactoryBean lt gt 扩展 ImportResourc
  • MATLAB算法实战应用案例精讲-【时序模型】循环神经网络-GRU(附MATLAB和Python代码)

    目录 前言 几个高频面试题 1 GRU与LSTM的区别与联系 2 LSTM和RNN的区别 GRU的引入 算法原理
  • 线性代数-方阵对角化及其应用

    前置知识 1 向量的内积 对于 a x 1
  • springboot常用注解详解

    在springboot中 经常会用到一些注解 它们各自代表着什么呢 在这个属于我们的节日里 快来了解一下吧 1 SpringBootApplication 一般不会主动去使用它 但是要知道它是一个组合注解 Configuration Ena
  • : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server versi

    出现这种报错的原因一定是sql语句写错了 报错 分析 解决方案 在这种报错的情况下 1 看字段是否写错 2 是否多逗号或者少写逗号 3 sql语句本身语法有没有错误
  • Uniapp零基础开发学习笔记(9) -媒体组件音视频摄像头等的练习使用

    Uniapp零基础开发学习笔记 9 媒体组件音视频摄像头等的练习使用 基础组件部分 最后就只剩余媒体组件以及地图 和画布Canvas 以及浏览器组件web view 此次先看看媒体组件 重点学习前面几个 链接如下 https uniapp
  • 阶段性目标规划

    1 2022 2023的目标 1 1 考证 1 软考 嵌入式系统工程师中级 2 架构师设计 1 2 研究产出 时间节点 2021 11 论文的修改与实验 操作系统 2021 12 Emd 与TQWT 算法的 选题与研究 与实验论文撰写 1
  • Kibana在Centos上开机启动

    1 需要下载kibana 去官网下 2 解压到自己指定的目录下 我是放到了 usr local下 3 执行 vi usr lib systemd system kibana service 插入下面内容 Unit Description k
  • Linux 压缩解包命令讲解

    tar命令使用讲解 压缩 tar命令 c 生成档案文件 v 列出归档解档的详细过程 f 指定档案文件名称 t 列出档案在包含的文件 x 解开档案文件 打包 tar cvf a tar txt tar cf a tar txt 解包 tar
  • YOLOv4 tensorrt推理 python版【附代码】

    学了几天的tensorRT 又经过了几天的努力终于实现了YOLOv4 tensorRT推理 这篇文章将把这些成果开源出来 供大家免费使用 YOLOv4代码我采用的是b站up主Bubbliiiing 相信大家应该都比较熟悉这位大佬 关于trt
  • Java实验三 基于GUI的网络通信程序设计【代码构建逻辑】【双向通信】【超多细节优化!!】

    写在前面 这次实验代码的构建主要是更加熟练的运用socket网络编程 文件输入输出流 GUI设计 容器的使用 多线程的运用等等多方面的知识 是综合类题型 做完受益身心的类型 题目如下 编写程序完成以下功能 1 设计一个基于GUI的客户 服务
  • DES加密算法详解——看这一篇就够了!

    目录 一 DES简介 二 DES算法入参 三 DES加密算法步骤解析 1 IP置换 M gt M0 2 密钥K控制的16轮运算 M0 K1 K16 gt M16 2 1 子密钥Kn的计算 2 1 1 PC 1置换 2 1 2 循环左移运算
  • 【C++】_5.模板

    目录 1 泛型编程 2 函数模板 2 1 概念 2 2 函数模板格式 2 3 函数模板原理 2 4 函数模板的实例化 2 5 函数模板的匹配原则 3 类模板 4 非类型模板参数 5 模板的特化 5 1 概念 5 2 函数模板特化 5 3 类
  • java项目抠图功能实现

    java项目抠图功能 项目中需要一个上传文字签名并且抠掉背景图的功能 当初第一次听到这个需求时 差点惊掉下巴 我压根都不会觉得java里能实现这功能 但是既然客户需要 那就照办吧 经过这次功能的实现 我也更加坚定了一个想法 再奇葩的需求 也
  • 斑马面试总结

    面试岗位 测试开发实习生 面试主要提问的是简历上的项目经历 测试相关的 给你一个视频软件 怎么测试 功能测试 黑盒测试 视频的封面正常 点击屏幕或播放键可以正常播放 视频时间倒计时显示正常 再次点击暂停 视频的声音 默认打开 无噪音 可以调
  • Ireport 报表设计部分填坑记录 基于Ireport 4.5.1

    Ireport 报表设计 基于Ireport 4 5 1 Ireport 换行遇到分页时 一行会被拆分为两行 断行 方式一 面板直接修改 点击detail栏的空白处 修改其 Split Type属性值为 Prevent 如果方式一 无法修改
  • Java 实现令牌桶限流算法 原生极简实现 包括单机和多线程版本

    文章目录 令牌桶算法简介 令牌桶算法限流范围 单机版实现 多线程版实现 令牌桶算法简介 令牌桶是指一个限流容器 容器有最大容量 每秒或每100ms产生一个令牌 具体取决于机器每秒处理的请求数 当容量中令牌数量达到最大容量时 令牌数量也不会改
  • Deque接口简介说明

    转自 Deque接口简介说明 下文笔者讲述Deque接口的简介说明 如下所示 Deque简介 Deque接口是一个双端队列 可以对队列的头尾进行操作 所以也可以当做栈来使用 Queue和Deque接口的相对应方法 Queue方法 Deque
  • d3dcompiler_43.dll丢失怎么修复?怎么解决

    在计算机使用过程中 我们经常会遇到一些错误提示 其中之一就是 找不到d3dcompiler 43 dll文件 那么 d3dcompiler 43 dll是什么文件 它的作用是什么 如果缺失了该如何修复呢 本文将详细介绍d3dcompiler

随机推荐

  • 【状态估计】基于无味卡尔曼滤波模拟倾斜传感器研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及讲解 1 概述 本文包括两部分中的第一部分 第一部分设计
  • VT Msr Hook Syscall

    VT Msr Hook Syscall 什么是系统调用 系统调用是内核提供给应用层的接口 比如在 win10x64 应用层打开一个应用 其实就是 explorer 调用了 CreateProcess 这个函数通过 NTDLL 调用表的 0x
  • 大数据技术——hadoop集群搭建出现的问题

    出现的问题和解决方案 ssh免密出现的问题 解决方法 出现上图的是语法错误 在ssh和 keygen中多了空格 去掉即可 2 ssh免密登录出现的问题 ssh登陆报错 WARNING REMOTE HOST IDENTIFICATION H
  • 区块链的工作原理

    区块链系统由数据层 网络层 共识层 激励层 合约层和应用层组成 其中 数据层封装了底层数据区块以及相关的数据加密和时间戳等基础数据和基本算法 网络层则包括分布式组网机制 数据传播机制和数据验证机制等 共识层主要封装网络节点的各类共识算法 激
  • tcp/ip 详细解析以及网络层简单的发送syn

    利用tcp发送syn 我们可以从网络层进行下发 其实就是组装tcp ip包发送出去 include
  • 微信小程序列表item左滑操作

    页面DOM index wxml
  • TLAB简单介绍

    1 什么是TLAB 新对象都是在Eden区分配空间 这块空间是在多线程间共享的 那么考虑一下 多线程是可能同时创建新对象的 这时候必然需要一种同步机制 使用队列 或者通过互斥 这些方式确实都可以 不过 我们还有一种更好的方式 TLAB 它全
  • 网络传输基本流程

    网络传输流程图 在数据链路层有一个标识 每一台主机的唯一符 MAC地址 MAC地址 计算机的网卡在出厂时就打上了一串数据 MAC 地址 其通常是唯一的 所以局域网中发消息必须加上目的主机的MAC地址 两台计算机通过 TCP IP 协议通讯的
  • 【算法笔记】Prim算法

    定义 prim算法 图论中的一种算法 可在加权连通图里搜索最小生成树 由此算法搜索到的边子集所构成的树中 不但包括了连通图里的所有顶点 并且其所有边的权值之和最小 算法描述 输入 一个加权连通图 其中顶点集合为V 边集合为E 初始化 Vne
  • Spring Cloud

    添加config properties文件就行了 内容为空的都可以 加上该文件再次运行
  • 如何防止CSRF攻击

    随着互联网的高速发展 信息安全问题已经成为企业最为关注的焦点之一 而前端又是引发企业安全问题的高危据点 在移动互联网时代 前端人员除了传统的 XSS CSRF 等安全问题之外 又时常遭遇网络劫持 非法调用 Hybrid API 等新型安全问
  • Lunece全文检索搜索引擎

    Lunece全文检索 1 什么是全文检索 lucene是apache软件基金会4 jakarta项目组的一个子项目 是一个开放源代码的全文检索引擎工具包 但它不是一个完整的全文检索引擎 而是一个全文检索引擎的架构 提供了完整的查询引擎和索引
  • Postman如何做接口测试,那些不得不知道的技巧

    目录 导读 前言 Postman如何做接口测试1 如何导入 swagger 接口文档 Postman如何做接口测试2 如何切换测试环境 Postman如何做接口测试3 什么 postman 还可以做压力测试 Postman如何做接口测试4
  • substance designer中的warp节点分析

    一直觉得warp挺适用 但是用起来有时候效果挺奇怪的 还有directional warp貌似两个产生的效果截然不同 于是尝试用u3d 材质实现下 directional warp 这个节点主要功能是用灰度信息推开像素 常常用来分割连续贴图
  • Ubuntu安装配置tftp服务器

    Ubuntu安装配置tftp服务器 实验环境 ubuntu 1604 x64 一 安装配置 建立tftp目录 sudo mkdir tftpboot sudo chmod 777 tftpboot 安装客户端和服务器 sudo apt ge
  • 大数据量的冒泡排序 (计次数)

    题目描述 给定一个包含从0到n 1各一次的数组 若使用冒泡排序将其排为升序 问其中需要进行多少次交换 输入 测试数据有多组 每组由两行组成 第一行包含正整数n n lt 5000 下一行包含从0到n 1的n个整数的序列 输出 对于每组测试数
  • [论文分享] Adversarial Training for Raw-Binary Malware Classifiers

    Adversarial Training for Raw Binary Malware Classifiers USENIX 2023 Keane Lucas Carnegie Mellon University Samruddhi Pai
  • 面试题61. 扑克牌中的顺子(java+python)

    从若干副扑克牌中随机抽 5 张牌 判断是不是一个顺子 即这5张牌是不是连续的 2 10为数字本身 A为1 J为11 Q为12 K为13 而大 小王为 0 可以看成任意数字 A 不能视为 14 示例 1 输入 1 2 3 4 5 输出 Tru
  • hex文件格式学习记录

    hex文件 hex文件是什么 hex文件的数据结构 按照记录类型具体分析 Mermaid Flowchart hex文件是什么 它是由一行行符合Intel HEX 文件格式的文本所构成的ASCII 文本文件 每一行包含一 个 HEX 记录
  • Java实验三 基于GUI的网络通信程序设计【代码构建逻辑】【双向通信】【超多细节优化!!】

    写在前面 这次实验代码的构建主要是更加熟练的运用socket网络编程 文件输入输出流 GUI设计 容器的使用 多线程的运用等等多方面的知识 是综合类题型 做完受益身心的类型 题目如下 编写程序完成以下功能 1 设计一个基于GUI的客户 服务