【JavaEE初阶 — 网络编程】TCP流套接字编程

news2024/11/30 0:58:03

      c96f743646e841f8bb30b2d242197f2f.gif

ddb5ae16fc92401ea95b48766cb03d96.jpeg692a78aa0ec843629a817408c97a8b84.gif


    TCP流套接字编程    


    1. TCP & UDP 的区别    


TCP 的核心特点是面向字节流,读写数据的基本单位是字节 byte 


    2 API介绍    


    2.1 ServerSocket    


     定义     


ServerSocket 是创建 TCP 服务端 Socket 的API。


     构造方法     


方法签名
 
方法说明
 
ServerSocket(int port)创建一个服务端流套接字Socket,并绑定到指定端口

所以服务器启动,需要绑定端口号


     方法      


方法签名
 
方法说明
 
 Socket accept()
 
开始监听指定端口(创建时绑定的端口),有客户端连接后,返回一个服务端Socket对象,并基于该Socket建立与客户端的连接,否则阻塞等待
 
 void close() 
 
关闭此套接字


    2.2  Socket    


  • Socket 是客户端 Socket ,或服务端中接收到客户端建立连接(accept方法)的请求后,返回的服务端Socket。

  • 不管是客户端还是服务端Socket,都是双方建立连接以后,保存的对端信息,及用来与对方收发数据的。

     构造方法     


方法签名方法说明
Socket(String host, int port)
 
创建一个客户端流套接字Socket,并与对应IP的主机上,对应端口的进程建立连接

这个方法的两个参数,都是服务器的IP & 端口,这个版本的构造方法,就是给客户端用的,服务器怎么通过这个类来构造对象呢?后续再来看;


     方法      


方法签名方法说明
InetAddress getlnetAddress()
 
返回套接字所连接的地址
 
InputStream getlnputStream()
 
返回此套接字的输入流
 
OutputStream getOutputStream()
 
返回此套接字的输出流

TCP没有 send(),receive() 这样的操作,但是 TCP 调用 getlnputStream() 会得到个 InputStream 对象;调用 getOutputStream(),得到一个 OutputStream 对象,这两个对象是字节流对象

虽然 Socket 自身没有读写操作,但是 Socket 可以拿到字节流对象,就可以通过字节流对象,来进行读写操作;


     3. 通过TCP实现回显服务器        


     TCP Echo Server    


    创建关联对象    


通过构造方法,绑定关联的端口号 (和 UDP类似,都是在构造对象的时候,绑定端口号)


    实现 start()    


    处理客户端发送的连接    


TCP 和 UDP 服务器 start() 的主循环的第一步有所区别:


  • UDP 进入主循环,就可以直接处理请求,根据请求计算响应,把响应返回客户端;
  • TCP服务器 ,进入主循环后,因为 TCP 是有连接的,所以第一步是先处理客户端发来的连接;
  • 这个连接就类似于打电话,在客户端打电话给服务器时,服务器要先接通电话,才可以进行后续的正常通信;

所以TCP服务器进入主循环的第一步,就是进行接通电话的操作,而拨号操作,是客户端来完成的;

调用 ServerSocket 对象底下的 accept() 方法,起到接听电话的作用;


还需要接收 accept() 方法的返回值:

  • 如果客户端和服务器确实已经建立连接了,那 accept() 是可以拿到这个请求连接的;
  • 如果客户端没有发起连接,那么 accept() 就会产生阻塞 ,和前面的 receive() 类似;

TCP 服务器后续通过对clientSocket 进行读写数据,来和客户端进行通信;


    进一步理解 ServerSocket 和 Socket 的职责划分    


    处理一个客户端的连接        

处理连接的过程比较复杂,因此我们把这个操作封装成一个方法;

可能会涉及到多个客户端的请求和响应,如果服务器接收到多个请求,就要返还给客户端多个响应;


    服务器与客户端成功连接,打印日志: 

这两个方法可以拿到对端(客户端)的 IP & 端口号;


    获取输入流对象&输出流对象     

打印出客户端的IP&端口号后,就需要进一步地处理客户端的请求和响应,需要借助 Socket 类内置的 InputStream & OutputStream 来处理这些请求和响应

这里获取到的是输入流对象,后续提供这个对象,来读取客户端的请求;


接下来获取输出流对象,并且处理异常:


拿到输入流对象&输出流对象后,后续读取请求,就使用输入流对象;返回响应,就把响应的内容写入输出流对象中; 


接下来,在 try 的代码块中,实现读取请求和返回响应的操作,这些操作分成三步

  1. 读取请求并解析 
  2. 根据请求计算响应
  3. 返回响应给客户端

因为在一次连接中,这三个操作可能会解析多次,所以我们提供 while 循环来处理


    读取请求    

下列操作,读取到的请求是一个字节数组,还需要手动把字节数组再转成字符串,才方便后续的处理和打印:


我们可以借助 Scanner 来进行更简单直接的读取操作,既可以读请求,读出来的请求又已经是一个字符串;

 

  • 把刚刚从 Socket 中拿到的 InputStream 填入 Scanner 中,后续通过 Scanner 直接读取请求中的内容;
  • 如果 Scanner 没有再读取到数据,说明连接断开,就可以结束循环了

所以读取请求,可以直接借助 read(),也可以借助 Scanner 来辅助完成

    补充     

  • Scanner 可以控制处理台输入,又可以控制处理文件的输入,还可以控制处理网络的输入;
  • Scanner 的构造方法:

  • Scanner 的构造方法,填入的是一个InputStream 对象

    根据请求计算响应    

  • 当前编写的是一个回显服务器代码,所以可以直接在计算响应的逻辑返回请求即可


     返回响应给客户端    

下列写法,会直接拿到 response 中的字节数组,然后通过 outputStream 提供的 write(),来写入输出流对象即可;

这种计算响应的方法,是提供字节的方式填充输出流对象;


除了上述写法,我们还可以利用字符流的方式:


这里的 writer 和 System.out 起到的的效果类似,所以 println,printf 等等都可以通过调用


    打印返回响应的日志和连接断开的日志    


    服务器一次连接可处理多个请求的原理   

服务器 start() 的代码块中, process() 方法处理请求返回响应的逻辑,相当于嵌套了两层 while 循环:

因此,可以在服务器与客户端的一次连接中,服务器处理多个请求;

如果在一次连接中,客户端发送多次请求,服务器就返还多个响应(打一次电话可以说一句话或者很多句话);


    补充     

  • 一个连接一个请求(短连接),一个连接多个请求(长连接);
  • 因为连接过程的开销非常大,所以在日常开发中,更主流的是长连接,一个连接处理多个请求;
  • 就好比锁消除,针对要加锁的多个逻辑,每个逻辑都进行加锁,开销非常大,所以更科学的做法是把这些逻辑合在一起,只进行一次加锁;(和领导汇报工作成果,应该在一次电话中一次性汇总完毕,而不是打多次电话。每次电话只汇报一个成果)

    TCP Echo Client    


     创建 Socket 对象    

Socket 在客户端和服务器都可以使用,服务器的 Socket 通过调用accept()拿到,但是客户端的 Socket 就需要通过实例来创建对象;

     实现客户端构造方法    

在客户端的构造方法中,传入服务器的IP和端口号;

传到构造方法中的字符串IP地址(类似127.0.0.1这样的字符串),不需要任何转换;


对比UDP 的客户端,TCP客户端在构造方法在实例Socket对象后,就会在底层和对端建立TCP连接,连接好后,服务器会记录对端的信息(实例化Socket对象时传入的IP和端口号);

因此,服务器的IP和端口号,在TCP客户端中就不需要再创建变量来保存了;


    从控制台中读取请求,发送给服务器    


    从控制台中读取用户输入信息作为请求    

为了实现客户端能够和服务器在一次连接的情况下,发送多次请求,我们设置一个循环:

这步操作可以读取刚刚输入控制台的一行信息,读取到的信息作为客户端的请求;


    拿到输入流&输出流    

之后就把这个请求写入 Socket 对象中,写的时候也需要拿到Socket对象的 InputStream 输入流& OutputStream 输出流;


为了使用方便,可以对拿到的输入流和输出流再套一层壳


    完善循环逻辑     

所以在主循环中,第一步操作是从控制台中读取用户输入,把读取到的输入设置为请求:


第二步就是把请求发送给服务器


第三步,就是读取服务器返回的响应,并且把读取到的响应打印到控制台


    客户端与服务器交互过程    


    区分客户端与服务器的 Socket 对象    

下列服务器和客户端的两个 socket 对象,分别在不同进程中,甚至在不同主机中,因此绝对不是同一个对象;

这两个对象存在密切的关联关系,可以把这两个 socket 对象理解为两部电话:

  • 接通这两部电话后,从A听筒说话,B可以听见;从B听筒说话,A可以听见(从一边对Socket对象写数据,另一边的 Socket 对象就可以读到);
  • 但是这两个对象绝对不是同一部电话;

    处理细节问题    

    问题一:冲刷缓冲区     

完善 main 方法


程序运行结果


关掉客户端:


再启动一次客户端,并且发送一个数据,并且一敲回车,发现没有反应:


为什么没有反应呢?因为其实刚刚客户端代码,并没有真的把请求发送出去:

这个操作只是把数据放到 “发送缓冲区” 中,还没有真正写入网卡里;


  •  发送缓冲区其实就是一块内存空间,对网络/硬盘写数据是一个非常低效的操作,如果频繁地调用这些比较低效的操作,程序运行是非常缓慢的;
  • 为了提高效率,就引入一个内存缓冲区,把要写入的数据都放入缓冲区中,再统一进行发送,这样可以减小写硬盘和写网络的次数;
  • 但是提高效率的同时,也会产生副作用,就是调用 writer.println 这样的操作,并没有真正地触发发送数据操作,而只是把数据写入缓冲区;
  • 当然,把数据写入缓冲区,而不是直接发送这样的行为,是 PrintWriter的行为,如果不套壳,是可以直接发送的;
  • 但是在实际开发中,广泛使用了缓冲区这样的概念,调用flush()来刷新缓冲区这个操作是非常关键的;

如何真正地把数据发送出去呢?我们要使用刷新操作(调用 flush() 方法来冲刷缓冲区),把缓冲区的数据强制写入 IO 设备中:


客户端服务器交互结果


    问题二:针对 hasNext 对一个完整请求/响应设置标识符    

 println 的操作,会自动加上一个 \n : 


但是如果在这个代码中不加这个 \n,直接使用 print行不行呢?


我们重新启动一下客户端,并且发送内容,发现客户端又没有反应了,并且服务器也没有读到信息:


造成上述原因,是因为 next() 的问题,修改成 print 后,客户端输入的数据也是发送到服务器上了,并且服务器也收到了,但是服务器并没有真正处理,因为服务器有一个hasNext()判断:


    补充    

  • hasNext() 的行为是,判断当前收到的数据是否包含“空白符”,什么是空白符呢?
  • 换行,回车,空格,制表符,翻页符......都是空白符;
  • 遇到空白符,hasNext()才会认为是一个完整的 next,否则在遇到空白符之前,hasNext() 都会阻塞。

所以刚刚在修改成 print 之后,发送的内容是不包含空白符的内容,hasNext() 就会阻塞而无法进入下面读取请求的逻辑;


    总结    


  • 使用 println,是在约定一个请求/响应,是在使用 \n 作为结束标记,对端在读取数据的时候,也会在读取到 \n 时,判断读取到一个完整的请求/响应;
  • 这是我们在使用TCP时,特别需要注意的事项,并且和UDP不一样;
  • UDP是以 DatagramPacket 作为单位的,但是TCP则是以字节为单位,但是实际上一个请求,往往是以多个字节构成的;
  • 到底多少个字节为一个完整的请求/响应,就需要程序员想办法标记出来,引入分割符是标记一次完整请求/响应的典型方式,不一定是换行,也可以是其他分割符; 

    问题三:根据不同Socket的生命周期判断是否需要手动关闭    

在TCP服务器刚刚编写的代码中,涉及两种Socket:

  • ServerSocket的生命周期,贯彻整个服务区进程,不需要手动关闭


  • clientSocket 的生命周期是一次连接,而不是整个服务器进程;

  • 所以每个客户端连接,都会创建一个新的 clientSocket,每个客户端断开,这个对象就应该 close() 了,但是当前代码并没有对 clientSocket 进行 close() 释放;
  • 没有在每次连接结束后,对 clientSocket 进行关闭,就会造成文件资源泄漏的问题(文件一直在打开,而不进行关闭,在打开到一定程度,会把文件描述表耗尽,就无法继续打开新文件)

  • 在 poccessConnection() 方法的逻辑执行完毕之后,我们就可以对 clientSocket 进行关闭

    总结    

  • 对于是否需要手动关闭 Socket ,需要我们分析请求它的生命周期是跟随整个进程,还是跟随某个环节;
  • 如果是跟随整个进程,那么可以不手动关闭 Socket;如果是每个请求都会创建应该 Socket,或者每一次连接都会创建一个 Socket,或者某一个环节的执行周期,会创建一个Socket,这样的情况,就需要我们手动关闭 Socket;
    问题四:服务器无法同时等待 accept() &等待已连接的客户端发送响应    

一个服务器能同时给多个客户端提供服务,那么刚刚编写的TCP服务器也可以处理多个请求吗?我们关掉客户端,再重新启动多个客户端:


    补充:修改同时启动多个客户端的IDEA设置    



IDEA 会默认只启动一个客户端,再启动别的客户端,会先关闭上一个启动的客户端;我们通过这里的设置,就可以让 IDEA 启动多个客户端;

设置好后,我们再来重新启动两个客户端, 并且先后发送请求:

结果在第二个客户端发送请求时,又卡住了,并且第一个创建的客户端多次发送请求的操作是没问题的,服务器都会有一个正常响应,但是第二个客户端无论怎么发送请求,都不会有响应:

并且我们通过服务器日志,可以发现,在第二个客户端上线时,并没有再次打印日志;

如果我们关掉第一个客户端,第二个客户端发送的请求,会马上被服务器接收,并且返回响应

所以当前代码,TCP服务器在同一时刻,只能处理一个客户端发送的请求;


针对上面出现的问题,我们对服务器的处理请求,返回响应这一块代码的关键逻辑进行分析:

如果同一时刻,有多个客户端对一个服务器进行连接,那么第一个和服务器连接的客户端1:

所以当前这个服务器代码,如果已经在处理一个客户端的请求,就没办法处理另一个客户端的请求,服务器代码会卡在循环中,无法重新调用 accept()连接新的服务器,直到连接的客户端退出,导致循环终止;


    总结    


  • 当前服务器代码,无法同时等待 accept 和 等待用户请求;在等待客户端发送请求的时候,没办法等待 accept() ,这个时候,如果有新的客户端连接,也无法接听电话(一个专业销售没办法在给先来的顾客讲解产品的时候,又去接待低级销售后面揽入店的顾客);
  • 因此,服务器的代码,导致服务器一次只能处理一个客户端发送的请求,这个代码是不合理的; 

    4. 服务器引入多线程    


如果只是单个线程,无法同时响应多个客户端;为了解决这个问题,此处给每个客户端都分配一个线程;


在服务器主线程中,就只是进行 accept(),每次有新的客户端 accept() 连接成功,就创建一个新的线程,又新线程负责完成,后续对客户端 Socket 对象的引用 clientSocket 的读写操作;

引入线程之后,重新启动服务器和两个客户端,可以发现服务器打印了两个带着不同端口号的日志;


因此,在引入线程之后,服务器可以一边等待请求,一边等待 accept() 连接新的客户端;



    5. 服务器引入线程池    


客户端连接,服务器就会创建新线程,客户端断开连接,客户端就会销毁线程,为了避免频繁创建销毁线程,也可以引入线程池;

线程池


对于在服务器引入线程池,一般不会使用 newFixedThreadPool,因为会创建一个固定线程数的线程池,意味着同时处理的客户端连接数目就固定了;

把任务都交到线程池中,线程池已经预先创建好了一些线程,提前创建好的线程就可以立刻投入工作,从而减少再去创建线程的开销;


线程不是越多越好,如果线程数量过多,CPU的利用率无法再被提高,还会导致系统调度速度下降;并且创建线程也是需要系统资源的,系统总体资源是有限的(一个主机差不多只能创建几千个线程);

无论是多线程,还是线程池,一个线程都对应一个客户端,并且一个主机创建的线程数目是有上限的,那如果有成千上万个客户端,同时访问一个服务器(一台主机),该怎么办呢?

IO多路复用/IO多路连接(这里不重点讲解,因为JVM中没有原生的 IO 多路复用 API,而是把API重新封装,已经不仅仅是多路复用了,后续会详细讲解针对 Java 的 IO多路复用所使用的 NIO,Netty 等知名网络框架,当前讲的IO是 BIO/Blocking IO);


    扩展    


基于BIO(同步阻塞IO)的长连接会一直占用系统资源。对于并发要求很高的服务端系统来说,这样的消耗是不能承受的。

  • 由于每个连接都需要不停的阻塞等待接收数据,所以每个连接都会在一个线程中运行。
  • 一次阻塞等待对应着一次请求、响应,不停处理也就是长连接的特性:一直不关闭连接,不停的处理请求。

实际应用时,服务端一般是基于NIO(即同步非阻塞IO)来实现长连接,性能可以极大的提升。 


    6. 长短连接    


TCP发送数据时,需要先建立连接,什么时候关闭连接就决定是短连接还是长连接;


    长连接和短连接的概念    


  • 短连接:每次接收到数据并返回响应后,都关闭连接,即是短连接。也就是说,短连接只能一次收发数据。
  • 长连接:不关闭连接,一直保持连接状态,双方不停的收发数据,即是长连接。也就是说,长连接可以多次收发数据。

    长连接和短连接区别    


  • 建立连接、关闭连接的耗时:短连接每次请求、响应都需要建立连接,关闭连接;而长连接只需要第一次建立连接,之后的请求、响应都可以直接传输。相对来说建立连接,关闭连接也是要耗时的,长连接效率更高。
  • 主动发送请求不同:短连接一般是客户端主动向服务端发送请求;而长连接可以是客户端主动发送请求,也可以是服务端主动发。
  • 两者的使用场景有不同:短连接适用于客户端请求频率不高的场景,如浏览网页等。长连接适用于客户端与服务端通信频繁的场景,如聊天室,实时游戏等。

   

   c96f743646e841f8bb30b2d242197f2f.gif

692a78aa0ec843629a817408c97a8b84.gif

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

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

相关文章

记录一次 k8s 节点内存不足的排查过程

背景:前端服务一直报404,查看k8s日志,没发现报错,但是发现pods多次重启。 排查过程: 查看pods日志,发现日志进不去。 kubectrl logs -f -n weave pod-name --tail 100查看pod describe kubectl describ…

Java文件遍历那些事

文章目录 一、简要概述二、文件遍历几种实现1. java实现2. Apache common-io3. Spring 三、最终结论 一、简要概述 文件遍历基本上是每个编程语言具备的基本功能,Java语言也不例外。下面我们以java原生实现,Apache common-io、spring框架实现为例来比较…

硬件基础22 反馈放大电路

目录 一、反馈的基本概念与分类 1、什么是反馈 2、直流反馈与交流反馈 3、正反馈与负反馈 4、串联反馈与并联反馈 5、电压反馈与电流反馈 二、负反馈四种组态 1、电压串联负反馈放大电路 2、电压并联负反馈放大电路 3、电流串联负反馈放大电路 4、电流并联负反馈放大…

【JS】React与Vue的异步编程对比:深度解析与实战案例全面指南

文章目录 前言更多实用工具React与Vue概述ReactVue 异步编程基础回调函数PromiseAsync/Await React中的异步编程使用Axios进行数据请求异步操作与组件生命周期React Hooks中的异步处理 Vue中的异步编程使用Axios进行数据请求异步操作与Vue生命周期Vue Composition API中的异步处…

【iOS】知乎日报总结

文章目录 前言首页网络请求轮播图上滑加载图片请求 文章详情页WKWebView的使用点赞、收藏持久化——FMDB的使用 其他问题沙盒问题单元格点击其他 总结 前言 在系统学习了OC语言和UI控件后,知乎日报是第一个比较大的项目,耗时一个多月时间,里面…

算法竞赛(Python)-链表

文章目录 一 链表简介1.1链表定义1.2 双向链表1.3 循环链表 二、链表的基本操作2.1 链表的结构定义2.2 建立一个线性链表2.3 求线性链表的长度2.4 查找元素2.5 插入元素2.5.1 链表头部插入元素2.5.2 链表尾部插入元素2.5.3 链表中间插入元素 2.6 改变元素2.7 删除元素2.7.1 链表…

Unity ShaderLab 实现网格爆炸

实现思路: 沿着3D物体每个面的法线,将面偏移一定的位置。 Shader Graph实现如下: Shader Lab 实现如下: Shader "Unlit/MeshExplode" {Properties{_MainTex ("Texture", 2D) "white" {}_Distan…

快速上手:如何开发一个实用的 Edge 插件

在日常浏览网页时,背景图片能够显著提升网页的视觉体验。如果你也想为自己的浏览器页面添加个性化背景图片,并希望背景图片设置能够持久保存,本文将介绍如何通过开发一个自定义Edge插件来实现这一功能。我们将涵盖保存背景设置到插件选项页&a…

【Maven】功能和核心概念

1. 什么是Maven 1.1 Maven的概念 Maven 是 Apache 软件基金会组织维护的一款自动化构建工具,专注服务于 Java 平台的项目构建和依赖管理。 1.2 为什么要使用Maven? 在项目开发中,我们需要引用各种 jar 包,引用的 jar 包可能有…

神经网络归一化方法总结

在深度学习中,归一化 是提高训练效率和稳定性的关键技术。以下是几种常见的神经网络归一化方法的总结,包括其核心思想、适用场景及优缺点。 四种归一化 特性Batch NormalizationGroup NormalizationLayer NormalizationInstance Normalization计算维度…

视频汇聚平台Liveweb国标GB28181视频平台监控中心设计

在现代安防视频监控领域,Liveweb视频汇聚平台以其卓越的兼容性和灵活的拓展能力,为用户提供了一套全面的解决方案。该平台不仅能够实现视频的远程监控、录像、存储与回放等基础功能,还涵盖了视频转码、视频快照、告警、云台控制、语音对讲以及…

hubu新星杯实践能力赛模拟赛web/Misc-wp

ez_eval <?php highlight_file(__FILE__); error_reporting(0);$hubu $_GET[hubu];eval($hubu);?> 先进行代码审计&#xff0c;GET传参hubu&#xff0c;并执行命令&#xff0c;没有任何绕过&#xff0c;放开手脚去做 payload: ?hubusystem(cat /f*); #直接rcerc…

【前端】跨域问题与缓存

报错如下&#xff1a; 原因&#xff1a; 浏览器 缓存跨域&#xff0c;顾名思义是由于浏览器的缓存机制导致的一种跨域情况。这种跨域一般会出现在浏览器通过一些无视跨域的标签和css(如img、background-image)缓存了一些图片资源之后&#xff0c;当再次发起图片请求时&#xff…

抓包之OSI七层模型以及TCPIP四层模型

写在前面 本文看下OSI七层模型以及TCP/IP四层网络模型&#xff0c;并尝试使用wireshark进行验证。 1&#xff1a;OSI七层网络模型和TCP/IP四层模型 全称&#xff1a;open system interconnection。 需要注意OSI七层模型最终是没有落地的&#xff0c;最终落地的是与之类似的…

#渗透测试#红蓝攻防#HW#漏洞挖掘#漏洞复现02-永恒之蓝漏洞

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

MTK 展锐 高通 sensorhub架构

一、MTK平台 MTK框架可以分为两部分&#xff0c;AP和SCP。 AP是主芯片&#xff0c;SCP是协处理器&#xff0c;他们一起工作来处理sensor数据。 SCP 是用来处理sensor和audio相关功能和其他客制化需求的一个协处理理器&#xff0c;MTK SCP选择freeRTOS作为操作系统&#xff0c…

视觉语言模型(VLM)学习笔记

目录 应用场景举例 VLM 的总体架构包括&#xff1a; 深度解析&#xff1a;图像编码器的实现 图像编码器&#xff1a;视觉 Transformer 注意力机制 视觉-语言投影器 综合实现 训练及注意事项 总结 应用场景举例 基于文本的图像生成或编辑&#xff1a;你输入 “生成一张…

[AutoSar]BSW_Diagnostic_007 BootLoader 跳转及APP OR boot response 实现

目录 关键词平台说明背景一、Process Jump to Bootloader二、相关函数和配置2.1 Dcm_GetProgConditions()2.2 Dcm_SetProgConditions() 三、如何实现在APP 还是BOOT 中对10 02服务响应3.1 配置3.2 code 四、报文五、小结 关键词 嵌入式、C语言、autosar、OS、BSW、UDS、diagno…

如何启用本机GPU硬件加速猿大师播放器网页同时播放多路RTSP H.265 1080P高清摄像头RTSP视频流?

目前市面上主流播放RTSP视频流的方式是用服务器转码方案&#xff0c;这种方案的好处是兼容性更强&#xff0c;可以用于不同的平台&#xff0c;比如&#xff1a;Windows、Linux或者手机端&#xff0c;但是缺点也很明显&#xff1a;延迟高、播放高清或者同时播放多路视频视频容易…

设置ip和代理DNS的WindowsBat脚本怎么写?

今天分享一个我们在工作时&#xff0c;常见的在Windows中通过批处理脚本&#xff08;.bat 文件&#xff09;来设置IP地址、代理以及DNS 相关配置的示例&#xff0c;大家可以根据实际需求进行修改调整。 一、设置静态IP地址脚本示例 以下脚本用于设置本地连接&#xff08;你可…