Socket安全(一)

news2024/11/25 0:49:09

文章目录

    • 1. 安全Socket
    • 2. 保护通信
    • 3. 创建安全客户端Socket
    • 4. 选择密码组
    • 5. 事件处理器
    • 6. 会话管理

1. 安全Socket

前面介绍了Socket的基本使用,这里开始介绍Socket的安全问题,作为一个Internet用户,你确实有一些保护手段可以保护自己的隐私不被泄露,为了使Internet连接从根本上上更加安全,可以对Socket进行加密,这可以保持事务的机密性、真实性和准确性。Java安全Socket扩展可以使用安全Socket层版本3和传输层安全协议以及相关算法来保护网络通信的安全。SS(Secure Sockets Layer,SSL)是一种安全协议,允许Web浏览器和其他TCP客户端基于各种级别的机密性和认证于HTTP和其他TCP服务对话。

2. 保护通信

经过开放通道(如公共Internet)的秘密通信绝对需要对数据加密。适合计算机实现的大多数加密机制是基于密钥思想的,密钥是一种更加一般化的口令,并不限于文本。明文消息根据一种数学算法与密钥的各个位组合,生成加密的密文。使用的密钥位数越多,通过强力猜测密钥的方法来解密就会越困难。在传统的密钥(或称为对称密钥)加密中,加密和解密数据都使用相同的密钥。发送方和接受方必须都知道这个密钥,所以发送消息之前发送方需要把这个密钥发送给接受方。但由于密钥是不能加密的,这导致第三方可以获取该密钥来偷窥发送方和接受方所有消息。在公开密钥(或非对称密钥)加密中,加密和解密数据使用不同的密钥。一个密钥称为公开密钥(public key),用于加密数据。这个密钥可以提供给任何人。另一个密钥称为私有密钥经济(private key),用于解密密钥。私有密钥必须保存好,只有通信中的一方拥有它。现在发送方给接受方发送了一条加密消息,接受方收到后向发送方询问公开密钥,这个公开密钥第三方也可以获取,但第三方并不能用这个公开密钥解密文件,因为解密需要接受方的私有密钥,所以在这种情况下信息是 安全的。非对称加密也可用于身份认证和消息完整性检查,这样接受方就能知道消息在传送过程中消息有没有被篡改。这样就保证了机密性、真实性和完整性。但非对称加密也不是绝对安全的,考虑下面场景:

第三方可以不攻击加密算法,而是攻击用于收发消息的协议,这种攻击不需要第三方破解密文,与密钥长度也完全无关。在接受方将其公开密钥发送给发送方是,第三方不只是可以读取这个公开密钥,还可以用他自己的公开密钥替换接受方的公开密钥。这样发送方就认为他正在使用接受方的密钥加密消息,其实使用的是第三方的公开密钥。然后继续发送给接受方。这样第三方就可以拦截到这个消息,使用自己的私有密钥解锁。这种攻击被称为中间人攻击

上面可以看出加密/解密算法还是很麻烦的事,幸运的是我们不需要成为密码专家就可以在java网络程序中使用强加密。JSSE掩盖了如何协商算法、交换密钥、认证通信双方和加密数据的底层细节。JSSE允许你创建Socket和服务器Socket,可以透明地处理安全通信中 必要的协商和加密。你要做的就是熟悉流和Socket来发送数据(前面的内容)。Java安全Socket拓展分为四个包:
java.net.ssl:定义Java安全网络API的抽象类
javax.net:替代构造函数创建安全Socket的抽象Socket工厂
java.security.cert:处理SSL所需公开密钥证书的类
com.sun.net.sslL:Sun公司的JSSE成参考实现中实现加密算法和协议的具体类。

3. 创建安全客户端Socket

如果不太关心底层的细节,使用加密SSL Socket与现有的安全服务器通信确实非常简单。并不是构造函数来构造一个java.net.Socket对象,而是从javax.net.ssl.SSLSocketFactory使用其createSocket()方法得到一个Socket对象。SSLSocketFactory使用遵循抽象工厂设计模式的抽象类。要通过调用静态SSLSocketFactory.getDefault()方法得到一个实例:

SocketFactory factory=SSLSocketFactory.getDefault();
Socket socket=factory.createSocket("login.ibiblio.org",7000);

一旦有了工厂的引用就可以使用下面5个重载方法createSocket()方法创建一个SSLSocket:

public abstract Socket createSocket(String host,int port) throws IOException,UnkonwHostException
public abstract Socket createSocket(InetAddress host,int port) throws IOException
//上面连个方法创建并返回一个连接到指定主机和端口的Socket
public abstract Socket createSocket(String host,int port,InetAddress interface,int localPort) throws IOException,UnkonwHostException
public abstract Socket createSocket(InetAddress host,int port,InetAddress interface,int localPort) throws IOException,UnkonwHostException
//上面两个方法创建并返回一个从指定本机网络接口和端口指定到指定主机和端口的Socket
public abstract Socket createSocket(Socket proxy ,String host,int port,boolean autoClose) throws IOException,UnkonwHostException
//上面的方法会使用到代理服务器

下面的代码会连接一个安全的HTTP服务器,发送简单的GET请求并显示响应

public class QuizCardBuilder {

    public static void main(String[] args) {
       int port=443; //默认的https端口
        SSLSocketFactory factory=(SSLSocketFactory) SSLSocketFactory.getDefault();
        SSLSocket socket=null;
        try{
            String host="www.baidu.com";
            socket=(SSLSocket) factory.createSocket(host ,port);
            //启用所有密码组
            String[] supported=socket.getSupportedCipherSuites();
            socket.setEnabledCipherSuites(supported);
            Writer out=new OutputStreamWriter(socket.getOutputStream(),"UTF-8");
            //https在get行中需要完全URL
            out.write("GET http://"+host+"/ HTTP/1.1\r\n");
            out.write("Host: "+host+"\r\n");
            out.write("\r\n");
            out.flush();
            //读取响应
            BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //读取首部
            String s;
            while(!(s=in.readLine()).equals("")){
                System.out.println(s);
            }
            System.out.println();
            //读取长度
            String contentLength=in.readLine();
            int length=Integer.MAX_VALUE;
            try{
                //16进制字符串转换为int类型
                length=Integer.parseInt(contentLength.trim(),16);
            }catch (NumberFormatException e){

            }
            System.out.println(contentLength);
            int c;
            int i=0;
            while((c=in.read())!=-1 && i++<length){
                System.out.println(c);
            }
            System.out.println();
        }catch (IOException ex){
            System.err.println(ex);
        }finally {
            try{
                if(socket!=null) socket.close();
            }catch (IOException e){}
        }
    }
}

在这里插入图片描述
运行这个程序会发现比之前直接使用Socket要慢,这是因为生成和交换密钥时,都有相当可观的CPU和网络开销。

4. 选择密码组

JSSE的不同实现支持认证和加密算法的不同组合。SSLSocketFactory中的getSupportedCipherSuited()方法可以指出给定Socket上可用的算法组合:

public abstract String[] getSupportedCipherSuites()

不过,并非所有能够理解的密码组都一定能在连接上使用。有些强度太弱,因而禁止使用。SSLSocketFactorygetEnabledCipherSuites()方法可以指出这个Socket允许使用哪些密码组:

public abstract String[] getEnabledCipherSuites()

实际使用的密码组要在连接时由客户端和服务器协商。可以通过setEnaledCipherSuites()方法修改客户端试图使用的密码组

public abstract void setEnabledCipherSuites(String[] suites)

这个方法的参数应当是希望使用的密码组列表,列表中的每一个名必须是getSupportedCipherSuites()列出的某个密码组。下面代码可以查看自己JDK支持的密码组:

public class QuizCardBuilder {

    public static void main(String[] args) {
        SSLServerSocketFactory sslServerSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
        String[] supportedCipherSuites = sslServerSocketFactory.getSupportedCipherSuites();

        System.out.println("Supported Cipher Suites:");
        for (String cipherSuite : supportedCipherSuites) {
            System.out.println(cipherSuite);
        }
    }
}

输出结果如下:

TLS_AES_256_GCM_SHA384
TLS_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_EMPTY_RENEGOTIATION_INFO_SCSV

每个名中的算法分为4个部分:协议、密钥交换算法和校验和。如TLS_AES_256_GCM_SHA384表示在TLS通信中使用AES加密算法(密钥长度为256位)和GCM加密模式进行数据加密,同时使用SHA384算法生成消息摘要。这个密码套件提供了强大的加密和安全性,用于保护通信数据的机密性和完整性。一般来讲,以TLS_ECDHE开头的并以SHA256或SHA384结尾的密码组是当前使用最广泛的加密算法。

DES和AES区别:它们是块加密(即一次加密一定数量的二进制位),DES总是加密64位,编码器需要使用额外的位填充输入。AES可以加密128、192或256位的块,但如果不是块大小的整数倍,仍然需要填充输入。RC4是一种流加密,可以一次加密一个字节,更适合一次发送一个字节的协议。

String[] strongSuites={"TLS_ECDHE_ECDSA_WITH_AES_128_CBC=SHA256"}
socket.setEnabledCipherSuites(StrongSuites);

如果连接另一端不支持这个加密协议,就会抛出异常。

5. 事件处理器

网络通信相对大多数计算机速度而言都很慢。认证的网络通信甚至更慢。安全连接所必需的密钥生成和建立过程会轻而易举地花费数秒钟时间。因此,你可能希望异步地处理连接。JSSE使用标准Java事件模型来通知程序,告诉它们客户端和服务器之间的握手何时完成。为了得到握手结束事件的通知,只需要实现HandshakeCompletedListener接口

public void HandshakeCompleted(HandshakeCompletedEvent event)
//获取与当前SSLSocket关联的SSLSession对象。
public SSLSession getSession()
//获取当前SSL连接使用的密码套件。返回一个字符串,表示正在使用的密码套件的名称。密码套件包括加密算法、哈希算法和密钥交换算法等
public String getCipherSuite()
//获取对等方(服务器)的证书链。返回一个X509Certificate数组,表示对等方的证书链。如果对等方没有提供有效的证书链,或者未进行验证,将抛出SSLPeerUnverifiedException异常。
public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException
//获取底层的SSLSocket对象。返回与当前SSLSocket对象关联的底层SSLSocket实例。可以使用这个方法来进一步操作底层的SSLSocket,例如获取底层的InputStream和OutputStream。
public SSLSocket getSocket()

通过addHandshakeCompletedListener()removeHandshakeCompletedListener()方法,特定的HandshakeCompletedListener对象可以注册对某个SSLSocket的握手结束事件的关注:

public abstract void addHandshakeCompletedListener(HandshakeCompletedListener listener)
public abstract void removeHandshakeCompletedListener(HandshakeCompletedListener listener)throws IllegalArgumentException

下面是使用的一个案例

 public static void main(String[] args) throws IOException {
        try {
            // 创建Socket并连接到服务器
            SSLSocketFactory socketFactory=(SSLSocketFactory) SSLSocketFactory.getDefault();
            SSLSocket socket= (SSLSocket) socketFactory.createSocket("www.qq.com",443);
            // 注册握手完成事件监听器
            socket.addHandshakeCompletedListener(HandshakeCompletedEvent-> {
                try {
                    LOGGER.info("Connected [" + HandshakeCompletedEvent.getSource() + ", " + socket.getSession().getPeerCertificateChain()[0].getSubjectDN() + "]");
                } catch (SSLPeerUnverifiedException e) {
                    LOGGER.log(Level.WARNING,e.getMessage(), e);
                }
            });
            //开始握手过程
            socket.startHandshake();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

在这里插入图片描述

6. 会话管理

SSL常用于web服务器,因为web连接一般是暂时的,每个页面需要单独的Socket,如果每个页面搜要花一定时间来协商一个安全连接,会需要大量的握手时间 ,会产生很大的开销。SSL允许建立扩展到多个Socket的会话。相同会话中的不同Socket使用同一组相同的公开密钥和私有密钥。使用JSSE不需要任何额外的工作,如果在很短的时间内对一台主机的一个端口打开多个Socket(注意同一时间一个端口只能绑定一个Socket),JSSE会自动重用这个会话的密钥,在JSSE中,会话由SSLSession接口的实例表示,可以使用这个接口的方法来检查会话的创建时间和最后访问时间、将会话作废、得到会话的各种信息等:

在基于TCP的Socket通信中,通过建立客户端和服务器之间的连接,可以进行双向的数据传输。这个连接可以被看作是一个会话,但并非在Socket层面上定义的会话。相反,在基于传输层安全性(TLS)的Socket通信中,会话(session)是一个概念,用于表示建立在安全传输层上的连接。在TLS会话中,包括以下内容:

  • 握手过程:在TLS会话开始时,客户端和服务器之间进行握手协商,包括协议版本、密码套件、加密算法等的协商过程。
  • 安全参数:在握手完成后,会话包含了一组安全参数,如会话密钥、证书、协商的加密算法等。
  • 会话重用:为了提高性能,TLS会话可以进行重用。客户端和服务器可以在之后的连接中重用之前建立的会话,避免重新执行完整的握手过程。

需要注意的是,TLS会话是在TLS/SSL协议层面定义的概念,并不是在标准的Socket层面上存在。因此,在使用标准的Socket通信时,并没有对会话的明确定义和管理。如果您需要在Socket通信中实现会话管理,您可以考虑使用其他协议或技术,如HTTP的会话管理(使用Cookie/Session)或WebSocket协议等。这些协议或技术在应用层面上提供了会话的概念和管理机制。

public byte[] getId()
public SSLSessionContext getSessionContext()
public long getCreationTime()
public long getLastAccessedTime()
public void invalidate()
public void putValue(String name,Object value)
public Object getValue(String name)
public void removeValue(string name)
public String[] getValueNames()
public String[] getValueNames()
public X509Certificate[] getPeerCertificateChain()throws SSLPeerUnverifiedException
public String getCipherSuite()
public String getPeerHost()

SSLSocket类的getSession()方法返回这个Socket所属的Session会话。不过会话和性能是一个折中。每一个事务都重新协商密钥会更加安全。为避免Socket创建会话,要向setEnableSessionCreation()传入false。在很少见的情况下,你甚至希望重新认证一个连接(也就是丢弃前面协商好的所有密钥和证书,重新开启一个新的会话), startHandshake()方法可以做到这一点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/588986.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

KUC755AE105 3BHB005243R0105 串行连接的自动配置

KUC755AE105 埃德蒙顿(pr web)-2007年5月23日-MatrikonOPC宣布为Allen-Bradley PLC发布MatrikonOPC服务器。该OPC服务器为所有Allen-3BHB005243R0105 分布式控制系统(DCS)提供了可靠的连接&#xff0c;代表了连接Allen-Bradley设备的真正的“一体化”解决方案。Allen-Bradley…

自动化测试中的失败截图和存log

如果我们在执行自动化测试的时候&#xff0c;希望能在失败的时候保存现场&#xff0c;方便事后分析。 对于UI自动化&#xff0c;我们希望截图在测试报告中。 对于api自动化&#xff0c;我们希望截取出错的log在测试报告中。 我开始自己蛮干&#xff0c;写了两个出错截图的方法。…

linux init系统和系统管理器-Systemd学习

一、Systemd 概述 1.1、init 程序介绍及其发展历程 Linux init程序是系统启动时第一个启动的进程&#xff0c;它负责初始化系统资源&#xff0c;加载操作系统核心模块&#xff0c;启动系统服务和用户进程。init程序是系统启动的重要组成部分&#xff0c;它为后续的系统操作提…

2023年上半年信息系统项目管理师上午真题及答案解析

1.“新型基础设施”主要包括信息技术设施、融合基础设施和创新基础设施三个方面。其中信息基础设施包括&#xff08; &#xff09;。 ①通信基础设施 ②智能交通基础设施 ③新技术基础设施 ④科教基础设施 ⑤算力基础设施 A.①③⑤ B.①④⑤ C.②③④ D.②…

【JavaSE】Java基础语法(三十六):File IO流

文章目录 1. File1.1 File类概述和构造方法1.2 绝对路径和相对路径1.3 File 类的常用方法1.4 递归删除文件夹及其下面的文件 2. IO2.1 分类2.2 字节输出流2.3 字节输入流2.4 文件的拷贝2.5 文件拷贝效率优化2.6 释放资源2.7 缓冲流2.8 编码表 3. commons-io 工具包3.1 API 1. F…

如何在竞争激烈的市场环境下打造技术铁粉:CSDN的案例分析

如何在竞争激烈的市场环境下打造技术铁粉&#xff1a;CSDN的案例分析 随着互联网的快速发展&#xff0c;技术平台不仅成为了人们获取信息、学习知识和交流经验的重要渠道&#xff0c;也成为了各大企业和个人展示自我、争夺市场份额的关键竞技场。在这个过程中&#xff0c;CSDN…

ts reference 报错 ReferenceError: AA is not defined解决方案

我先说重点&#xff01;你看懂了就不用往下看了 ///<reference path"2.ts" /> 像上面这种代码是要编译后才有效果的&#xff0c;所以有些小伙伴发现教程demo也跑不了&#xff0c;跟命名空间啥的没关系&#xff01; 正文 你如果也报我我下面这种错误&#xff…

【智慧交通项目实战】《 OCR车牌检测与识别》(一)

&#x1f468;‍&#x1f4bb;作者简介&#xff1a; CSDN、阿里云人工智能领域博客专家&#xff0c;新星计划计算机视觉导师&#xff0c;百度飞桨PPDE&#xff0c;专注大数据与AI知识分享。✨公众号&#xff1a;GoAI的学习小屋 &#xff0c;免费分享书籍、简历、导图等&#xf…

西南财经大学李玉周:数智化技术广泛使用推动管理会计加快落地

近日&#xff0c;由用友主办的「智能会计 价值财务」2023企业数智化财务创新峰会收官站圆满举办。来自知名院校的专家学者、央国企等大型企业财务领路人相约成都&#xff0c;一同见证“智能会计”新时代的到来&#xff0c;并肩探讨“价值财务”新主张。 为更好传递智能会计对企…

UnityVR--插件1--新版InputSystem

目录 新版的InputSystem 安装新版InputSystem插件 配置新的InputSystem 在项目中配置新版输入方式实现移动和开火 添加并绑定移动事件 添加并绑定开火事件 总结&#xff08;啰嗦几句&#xff09; 新版的InputSystem 在最初的Unity系统中&#xff0c;只有键盘、鼠标、操作…

html实现好看的浪漫爱情回忆录(附源码)

文章目录 1.设计来源1.1 主界面1.2 主题描述1.3 照片墙详细界面1.4 相关跳转界面 2.效果和源码2.1 效果演示2.2 源代码 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/130946811 html实现好看的浪漫爱情回忆录…

Unity发布WebGL报错il2cpp.exe did not run properly

解决&#xff1a;路径中不能有任何中文&#xff0c;包括用户名都不能是中文 win10修改用户名为英文&#xff1a; 1、开启administrator账户。 1&#xff09;、右键我的电脑&#xff0c;选择管理。 2&#xff09;、本地用户和组—用户—Administrator 3&#xff09;、右键—属性…

C++11新特性:decltype类型推导

上一节所讲的 auto&#xff0c;用于通过一个表达式在编译时确定待定义的变量类型&#xff0c;auto 所修饰的变量必须被初始化&#xff0c;编译器需要通过初始化来确定 auto 所代表的类型&#xff0c;即必须要定义变量。若仅希望得到类型&#xff0c;而不需要(或不能)定义变量的…

yum安装最新版的PHP、MySQL

本地环境&#xff1a;AlmaLinux9.2 在阿里的镜像源站点有一个叫remi的源&#xff0c;这个源专门提供了php的各种版本&#xff0c;目前这个源只针对Redhat、Centos和Fedora系统 Remi镜像简介 Remi镜像主页 配置Remi镜像源 这里以Enterprise Linux 9 为例 配置向导 根据配置向…

关于机器人状态估计(15)-VIO与VSLAM精度答疑、融合前端、主流深度相机说明与近期工程汇总

VIOBOT种子用户有了一定的数量&#xff0c;日常大家也会进行交流&#xff0c;整理总结一下近期的交流与答疑。 VIO-SLAM(作为三维SLAM&#xff0c;相对于Lidar-SLAM和LIO-SLAM)在工程上落地的长期障碍&#xff0c;不仅在算法精度本身&#xff0c;还有相对严重的鲁棒性问题&…

【Linux】iptables防火墙

文章目录 一、Linux防火墙基础1.Linux防火墙概术2.netfilter/iptables3.四表五链4.规则链之间的匹配顺序 二、iptables 安装1.常用的控制类型2.常用的管理选项 三、示例演示1.添加新的规则2.查看规则列表3.删除规则4.清空规则 四、规则的匹配1.通用匹配2.隐含匹配3.显式匹配 一…

浅谈安科瑞无线测温技术在大功率整流器上的应用

安科瑞 徐浩竣 江苏安科瑞电器制造有限公司 zx acrelxhj 摘要&#xff1a;随着整流器运行电流的增加 &#xff0c;运行温度成为影响整 流器安全运行的主要因素 。针对目前大功率整流器运行温度通过出口水温表和纽扣继电器来监测 &#xff0c;运行人员不能及时、准确地掌握整…

【测试开发】第四节.测试开发(测试分类)

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;Java测试开发 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目录 前…

程序员有哪些绝对不能踩的坑?

本文概要 程序员编写高质量、可维护、安全且高效的代码&#xff0c;通常需要大量研究和经验。但也需要避免许多技术陷阱。一起来聊聊程序员有哪些绝对不能踩的坑吧&#xff01; &#x1f31f;&#x1f31f;&#x1f31f;个人简介&#x1f31f;&#x1f31f;&#x1f31f; ☀️…

Spring Boot拦截器与过滤器的区别

Spring Boot拦截器与过滤器的区别 在使用Spring Boot开发Web应用程序时&#xff0c;您可能需要在处理请求之前或之后执行某些操作。这些操作可以包括身份验证、日志记录、性能监测等。在这种情况下&#xff0c;您可以使用两种不同的机制&#xff1a;拦截器和过滤器。本文将介绍…