【JAVA CORE_API】Day18 网络编程、线程、在线聊天室v1.0

C/S:客户端/服务器端,所有网络应用都是基于客户端服务器端进行的,Java写的是服务端,客户端是一个软件,服务端也是一个软件,两个软件之间交互;(只能连接对应的服务器)

B/S:浏览器/服务器端,它本质上也是C/S,只不过它的C是一个浏览器而已;(连接任意服务器都可以、百度、淘宝、京东等)

聊天室:两个程序A和B,一个是客户端、一个是服务端:谁发起连接,谁是客户端;谁接收连接,谁是服务端。

想连在一起需要网络,目的是为了传输数据,发送数据的过程中时需要遵守一些协议的:
TCP协议:可靠传输协议,发送数据后需要对方确认,对方确认后才能继续发送数据,再需要对方确认,100%所有数据发送过去,比较像打电话,需要接电话才能听见。虽然说数据完全可靠,但效率低下;
UDP:不可靠传输协议,只管发,不管对方能否接收到,有点像大广播,播了就播了,不管你听没听见。虽然不能保证数据100%都发送成功,但是效率比较高。

但是我们学习的时候学TCP,因为日后面对的客户端都是B(浏览器),而浏览器和客户端之间采用的协议是Http协议,Http协议要求地下客户端服务端传输时必须建立在可靠传输协议TCP上。

网络编程

什么是Socket编程

什么是Socket编程

  • java.net.SocketJava提供的用于进行网络编程的API;

  • Socket编程可以让软件与软件之间以计算机作为载体,以网络作为信息流动的通道进行远端数据传递,达到交流的目的。

什么是计算机网络

  • 计算机网络是指将具有独立功能的多台计算机通过通信线路连接起来,实现数据共享和交流的计算机系统。

什么是Socket

  • Socket(套接字):网络通信的标准API、进行可靠的网络通讯。

Socket通讯

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

IP地址(楼)

在这里插入图片描述

端口(门)

在这里插入图片描述

IP+端口

在这里插入图片描述

客户端与服务端(C/S)

在这里插入图片描述

Socket通讯

在这里插入图片描述

在这里插入图片描述

ServerSocket

在这里插入图片描述
在这里插入图片描述

多客户端支持

如何接受多客户端

  • ServerSocket提供方法:

    • Socket accept():用于监听服务端口,一旦一个客户端连接即返回一个Socket

    • 多次调用该方法可以感知多个客户端的连接。

在这里插入图片描述

建立连接

建立连接

  • Server.java

     package socket;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;/*** 服务端*/public class Server {/*** java.net.ServerSocket:* 运行在服务端,主要作用两个:* 1.向系统申请服务端口,客户端通过该端口与服务端建立连接* 2.监听服务端口,一旦有客户端连接了,就会立即创建一个Socket对象与客户端进行交互*   如果将Socket比喻为"电话",那ServerSocket就相当于客户中心的"总机"*/private ServerSocket serverSocket;public Server(){try {System.out.println("正在启动服务器");/*** 创建ServerSocket对象时,会申请一个端口* 如果该端口被其它程序占用,会抛出异常:*   java.net.BindException: Address already in use:* 解决办法:* 1.更换端口号* 2.杀死占用该端口的进行(通常由于服务端启动两次导致)*/serverSocket = new ServerSocket(8088);System.out.println("服务器启动完毕");} catch (IOException e) {e.printStackTrace();}}/*** 该方法用于启动程序的执行*/public void start(){try {System.out.println("等待客户端连接...");/*accept():用于接收客户端连接,并返回一个Scoket对象与所连接的客户端进行交互该方法是一个阻塞方法,调用后程序会"卡住",直接一个客户端连接为止*/Socket socket = serverSocket.accept();System.out.println("一个客户端连接了!");} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {Server server = new Server();server.start();}}
    
  • Client.java

    package socket;
    import java.io.IOException;
    import java.net.Socket;
    /*** 客户端*/
    public class Client {/*java.net.Socket:套接字它封装了TCP协议的通信细节,使用它可以和服务器建立连接并进行交互*/private Socket socket;public Client(){try {System.out.println("正在连接服务端...");/*实例化Socket对象,就是与远端计算机建立连接的过程需要传入两个对数:1.服务端的IP地址,用于找到网络上对方的计算机2.服务端口,用于找到服务端计算机上的应用程序查看IP操作:Windows: win+r,输入cmd,回车,输入ipconfig,IPv4就是IP地址Mac:触控板上五指向中间抓,选择"终端"程序打开,输入/sbin/ifconfig查看IP地址*/socket = new Socket("localhost",8088);System.out.println("服务端连接成功!");} catch (IOException e) {e.printStackTrace();}}/*** 该方法用于启动客户端程序的执行*/public void start(){}public static void main(String[] args) {Client client = new Client();client.start();}
    }
    
  • 注意在尝试连接本地时要提前打开服务端Server.java,再连接自己,之后就可以通过其他人给出的端口号及IP地址连接其他人。

客户端发送文本数据

  • 利用IO只是中的流连接,使用客户端的Socket获取输出流进行流连接,利用PrintWriter来实现发送一行字符串的操作。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Server.java

package day18;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;/*** 服务端*/
public class Server {/*** java.net.ServerSocket:* 运行在服务端,主要作用有两个:* 1.像系统申请服务端口,客户端通过该端口与服务端建立连接* 2.监听服务端口,一旦有客户链接了,就会立即创建一个Socket对象与客户端进行交互*      如果将Socket比喻为“电话”,那ServerSocket就相当于客户中心的“总机”。* 解决方法:* 1.更换端口号;* 2.杀死占用该端口的进行(通常由于服务端启动了两次导致)*/private ServerSocket serverSocket;public Server(){try {System.out.println("正在启动服务端......");serverSocket = new ServerSocket(8888);System.out.println("服务端启动完成!");} catch (IOException e) {e.printStackTrace();}}// 启动服务端方法:public void start(){try {while (true){System.out.println("服务端正在等待客户端连接......");/*** accept():* 用于接收客户端连接,并返回一个Socket对象与所连接的客户端进行交互* 该方法是一个阻塞方法,调用后程序会“卡住”,直到一个客户端连接为止*/Socket socket = serverSocket.accept();System.out.println("一个客户端连接了!");// 接收客户端发送过来的消息InputStream inputStream = socket.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String message;while ((message = bufferedReader.readLine()) != null) {    // 读取客户端发送过来的消息System.out.println("客户端说:" + message);}}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {Server server = new Server();server.start();}}

Client.java

package day18;
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;/*** 客户端*/
public class Client {/*** java.net.Socket:套接字* 它封装了TCP协议的通信细节,使用它可以和服务器建立连接并进行交互* 可以理解为是电话*/private Socket socket;public Client() {// 实例化Socket对象,就是与远端计算机建立连接的过程// 需要传递两个对数:// 1.远端计算机的IP地址,用于找到网络上对方的计算机// 2.远端计算机的端口号,用于找到对方计算机中的应用程序try {System.out.println("正在连接服务端......");/*** 如何查找本机IP地址:* Windows:Win+R,输入cmd,回车,输入ipconfig,回车* Mac:触控板上五指向中间抓,选择"终端"程序打开,输入/sbin/ifconfig查看IP地址*/socket = new Socket("172.40.140.102", 8088);System.out.println("连接成功!");} catch (IOException e) {e.printStackTrace();}}// 该方法用于启动客户端程序的执行public void start() {// 通过Socket获取输出流用于向服务端发送消息try {OutputStream outputStream = socket.getOutputStream();OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);PrintWriter printWriter = new PrintWriter(bufferedWriter,true);  // 自动行刷新Scanner scanner = new Scanner(System.in);while (true) {String line = scanner.nextLine();if ("exit".equalsIgnoreCase(line)) {break;}printWriter.println(line);  // 发送消息给服务端}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {Client client = new Client();client.start();}
}

三次握手与四次挥手

客户端断开连接的操作

  • 我们在上方代码中输入“exit”后,服务器会出现一大堆红字;

什么是三次握手四次挥手

  • 异常出现的原因:

    • TCP协议是面向连续的可靠传输协议,双方建立连接及断开连接需要双向确认后才可以进行

    • 当任意一方在没有进行确认断开操作就擅自结束,另一方就会出现该异常。

  • 三次握手与四次挥手:

    • 客户端与服务端建立TCP连接时需要进行三次握手,以确保双方可以建立可靠连接;

    • 任意一方需要断开TCP连接时需要进行四次挥手,以确保双方可靠断开。

三次握手(Three-way Handshake)

  • 第一次握手(SYN):

    • 客户端发送一个带有SYN(同步)标志的数据包到服务器,并指定客户端的初始化序列号(ISN);

    • 客户端进入SYN_SENT状态,以等待服务器的确认。

  • 第二次握手(SYN-ACK):

    • 服务器收到客户端的SYN数据包后,会发送一个带有SYNACK(确认)标志的数据包到客户端,确认客户端的请求,并指定服务器的初始化序列号(ISN)。

    • 服务器进入SYN_RCVD状态;

  • 第三次握手(ACK):

    • 客户端收到服务器的SYN-ACK数据包后,会发送一个带有ACK标志的数据包给服务器,表示确认连线请求;

    • 服务器收到客户端的ACK后,双方都进入ESTABLISHED状态,建立起可靠的连接。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四次挥手(Four-way Wavehake)

  • Socket提供方法:

    • void close():用于和对方断开TCP连接,底层会进行四次挥手操作。

在这里插入图片描述

  1. 客户端发送FIN报文:客户端首先向服务器发送一个带有FIN标志位的保温,表示客户端不再发送数据,并请求关闭连接。此时客户端进入“FIN_WAIT_1”状态;

  2. 服务器发送ACK报文:服务器收到客户端的FIN报文后,会发送一个确认保温,即ACK报文,告知客户端已经收到关闭请求。此时服务器进入“CLOSE_WAIT”状态,等待确认关闭;

  3. 服务器发送FIN报文:服务器在发送ACK报文后,会继续检查是否还有剩余的数据需要发送。如果有,服务器会继续发送数据;如果没有,服务器会发送一个带有FIN标志位的报文给客户端,表示服务器也不在发送数据了。此时服务及进入“LAST_ACK”状态;

  4. 客户端发送ACK报文:客户端收到服务器的FIN报文后,会发送一个确认报文,即ACK报文,告知服务器已经收到关闭请求,并进入“TIME_WAIT”状态。再“TIME_WAIT”状态下,客户端等待一段时间(通常为2倍的最大报文段生存时间,即MSL),以确保服务器已经收到了ACK报文;

  5. 服务器收到ACK报文:服务器收到客户端的ACK报文后,确认客户端已经收到了服务器的关闭请求,此时服务器进入“CLOSED”状态,完成连接的关闭。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

 package day18;import java.io.*;import java.net.Socket;import java.nio.charset.StandardCharsets;import java.util.Scanner;/*** 客户端*/public class Client {/*** java.net.Socket:套接字* 它封装了TCP协议的通信细节,使用它可以和服务器建立连接并进行交互* 可以理解为是电话*/private Socket socket;public Client() {// 实例化Socket对象,就是与远端计算机建立连接的过程// 需要传递两个对数:// 1.远端计算机的IP地址,用于找到网络上对方的计算机// 2.远端计算机的端口号,用于找到对方计算机中的应用程序try {System.out.println("正在连接服务端......");/*** 如何查找本机IP地址:* Windows:Win+R,输入cmd,回车,输入ipconfig,回车* Mac:触控板上五指向中间抓,选择"终端"程序打开,输入/sbin/ifconfig查看IP地址*/socket = new Socket("localhost", 8888);System.out.println("连接成功!");} catch (IOException e) {e.printStackTrace();}}// 该方法用于启动客户端程序的执行public void start() {// 通过Socket获取输出流用于向服务端发送消息try {OutputStream outputStream = socket.getOutputStream();OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);PrintWriter printWriter = new PrintWriter(bufferedWriter,true);  // 自动行刷新Scanner scanner = new Scanner(System.in);while (true) {String line = scanner.nextLine();if ("exit".equalsIgnoreCase(line)) {break;}printWriter.println(line);  // 发送消息给服务端}} catch (IOException e) {e.printStackTrace();} finally {try {socket.close();  // 进行四次挥手} catch (IOException e) {e.printStackTrace();}}}public static void main(String[] args) {Client client = new Client();client.start();}}

多线程

概念

什么是线程与多线程

  • 线程是一个单一的顺序执行流程;

  • 多线程是多个单一顺序执行流程一起执行。

顺序执行与并发执行

  • 顺序执行:程序从上至下一句一句执行;

  • 并发执行:多个线程一起执行称为“并发执行”。

使用场景

  • 互不干扰:多线程通常用于在一个程序中需要同时处理多个互不干扰的任务;

  • 多线程更快:单线程可以完成,但是多线程更快。

单线程和多线程比喻

  • 可以把单线程看作只有一个灶台,一次只能做一道菜;或看作电路中的串联;

  • 多线程则是有很多灶台,一次能做很多菜;或看作电路中的并联。

CPU与多线程

CPU 的多线程操作通过时间片轮转Time Slicing)来实现。虽然一个 CPU 在某一时刻只能执行一个线程,但它可以在多个线程之间快速切换,使得每个线程都能获得一定的执行时间。这种快速的切换让用户感觉多个线程是同时运行的。

线程的创建

第一种创建线程形式

  • 继承Thread来定义一个线程:

    • 重写run方法,在其中定义该线程的任务代码。
 package day18;/*** 线程的第一种创建方式:继承Thread类* 更方便地使用匿名内部类创建线程、结构简单* 缺点:Java是单继承的,所以不能再继承其他类*      意味着继承了Thread就无法再继承其他类了,不利于复用*      定义线程的同时定义了线程的任务,导致线程和任务绑定在了一起,不利于复用*/public class ThreadDemo01 {public static void main(String[] args) {Thread thread01 = new MyThread01();Thread thread02 = new MyThread02();// 启动线程要调用star(),而不是直接调用run()方法thread01.start();thread02.start();}}class MyThread01 extends Thread {public void run() {for (int i = 0; i < 1000; i++) {System.out.println("Hi!" + i);}}}class MyThread02 extends Thread {public void run() {for (int i = 0; i < 1000; i++) {System.out.println("ByeBye!" + i);}}}

第二种创建线程的方式

  • 启动线程:

    • 实例化线程任务;

    • 实例化线程,同时将任务通过现成的构造器传递给线程;

    • 调用线程的start()方法。

 package day18;/*** 第二种创建线程的方式:实现Runnable接口*/public class ThreadDemo02 {public static void main(String[] args) {// 创建线程任务Runnable runnable01 = new MyRunnable01();Runnable runnable02 = new MyRunnable02();// 创建线程Thread thread01 = new Thread(runnable01);Thread thread02 = new Thread(runnable02);// 启动线程thread01.start();thread02.start();}}class MyRunnable01 implements Runnable {@Overridepublic void run() {for (int i = 1; i <= 1000; i++) {System.out.println("Hello!" + i);}}}class MyRunnable02 implements Runnable {@Overridepublic void run() {for (int i = 1; i <= 1000; i++) {System.out.println("Hi!" + i);}}}

使用匿名内部类实现线程的两种创建方式

 package day18;/*** 使用匿名内部类方式实现线程的两种创建方式*/public class ThreadDemo03 {public static void main(String[] args) {//第一种创建方式:继承Thread并重写run方法Thread thread01 = new Thread() {public void run() {for (int i = 0; i < 100; i++) {System.out.println("线程01:" + i);}}};thread01.start();//第二种创建方式:实现Runnable接口并重写run方法Thread thread02 = new Thread(() -> {for (int i = 0; i < 100; i++) {System.out.println("线程02:" + i);}});thread02.start();}}

并发解决聊天室不能多用户使用问题

 package day18;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.ServerSocket;import java.net.Socket;import java.nio.charset.StandardCharsets;/*** 服务端*/public class Server {/*** java.net.ServerSocket:* 运行在服务端,主要作用有两个:* 1.像系统申请服务端口,客户端通过该端口与服务端建立连接* 2.监听服务端口,一旦有客户链接了,就会立即创建一个Socket对象与客户端进行交互*      如果将Socket比喻为“电话”,那ServerSocket就相当于客户中心的“总机”。* 解决方法:* 1.更换端口号;* 2.杀死占用该端口的进行(通常由于服务端启动了两次导致)*/private ServerSocket serverSocket;public Server(){try {System.out.println("正在启动服务端......");serverSocket = new ServerSocket(8888);System.out.println("服务端启动完成!");} catch (IOException e) {e.printStackTrace();}}// 启动服务端方法:/*** accept():* 用于接收客户端连接,并返回一个Socket对象与所连接的客户端进行交互* 该方法是一个阻塞方法,调用后程序会“卡住”,直到一个客户端连接为止*/public void start(){try {while (true){System.out.println("服务端正在等待客户端连接......");Socket socket = serverSocket.accept();System.out.println("一个客户端连接了!");// 启动单独的线程来处理与客户端的通信ClientHandler clientHandler = new ClientHandler(socket);Thread thread = new Thread(clientHandler);thread.start();}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {Server server = new Server();server.start();}/*** 该线程任务用于负责与指定的客户端通信*/private class ClientHandler implements Runnable{private Socket socket;public ClientHandler(Socket socket) {this.socket = socket;}@Overridepublic void run() {try {// 接收客户端发送过来的消息InputStream inputStream = socket.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String message;while ((message = bufferedReader.readLine()) != null) {    // 读取客户端发送过来的消息System.out.println("客户端说:" + message);}} catch (IOException e) {e.printStackTrace();} finally {try {serverSocket.close();} catch (IOException e) {e.printStackTrace();}}}}}

主线程

  • Java程序的任何代码都是靠线程进行,main方法也是;

  • 程序启动后,JVM创建一条线程执行main方法,这条线程我们叫“主线程main”;

什么是主线程

  • Thread提供的静态方法:

    • static Thread currentThread()

    • 该方法用于返回执行他的线程;

查看线程的相关信息

  • Thread提供了获取线程信息的相关方法:

    • long getId():返回该线程的标识符;

    • String getName():返回该线程的名称;

    • int getPriority():返回线程的优先级;

    • boolean isAlive():检测线程是否处于活跃状态;

    • boolean isDeamon():测试线程是否为守护线程;

    • boolean isInterrupted():测试线程是否已经中断;

 package day18;import static java.lang.Thread.currentThread;/*** 线程信息*/public class ThreadInfoDemo {public static void main(String[] args) {Thread main = currentThread();  // 获取主线程System.out.println(main);doSome();  // 主线程调用doSome方法}public static void doSome() {Thread t = currentThread();  // 获取的是doSome方法的线程System.out.println("运行doSome方法的线程:" + t);System.out.println("运行doSome方法的线程名称:" + t.getName());System.out.println("运行doSome方法的线程优先级:" + t.getPriority());System.out.println("运行doSome方法的线程是否是守护线程:" + t.isDaemon());System.out.println("运行doSome方法的线程是否是活动线程:" + t.isAlive());System.out.println("运行doSome方法的线程是否是中断状态:" + t.isInterrupted());System.out.println("运行doSome方法的线程标识符:" + t.getId());}}

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

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

相关文章

吐血整理 ChatGPT 3.5/4.0/4o 新手使用手册~

都知道ChatGPT很强大&#xff0c;聊聊天、写论文、搞翻译、写代码、写文案、审合同等等&#xff0c;无所不能~ 那么到底怎么使用呢&#xff1f;其实很简单了&#xff0c;国内AI产品发展也很快&#xff0c;很多都很好用了~ 我一直在用&#xff0c;建议收藏下来~ 有最先进、最…

基于 Appium 的 App 爬取实战

除了运行 Appium 的基本条件外&#xff0c;还要一个日志输出库 安装&#xff1a; pip install loguru 思路分析 首先我们观察一下整个 app5 的交互流程&#xff0c;其首页分条显示了电影数据&#xff0c; 每个电影条目都包括封面&#xff0c;标题&#xff0c; 类别和评分 4…

Godot《躲避小兵》实战之创建玩家场景

项目设置完之后&#xff0c;我们就可以开始处理玩家控制的角色。 这里我们将玩家放在一个单独的场景当中&#xff0c;这样做的好处是在游戏的其他部分做出来之前&#xff0c;我们就可以对其进行单独测试。 节点结构 场景是一个节点树结构&#xff0c;因此一个场景需要有一个…

WordPress美化节日灯笼插件,适合春节的时候使用

源码介绍&#xff1a; WordPress美化节日灯笼插件&#xff0c;适合每年过年的时候安在网站上使用&#xff0c;这款插件可以备用着&#xff0c;一款WordPress节日灯笼美化插件&#xff0c;可以给网页自动加一个灯笼效果使用说明&#xff1a;到网站WP后台 - 插件 - 安装插件 - 上…

[C#]基于winform结合photocartoon算法实现人物卡通化源码实现

【官方框架】 https://github.com/minivision-ai/photo2cartoon 简介 人像卡通风格渲染的目标是&#xff0c;在保持原图像ID信息和纹理细节的同时&#xff0c;将真实照片转换为卡通风格的非真实感图像。我们的思路是&#xff0c;从大量照片/卡通数据中习得照片到卡通画的映射…

企业级web应用服务器tomcat

目录 一、Web技术 1.1 HTTP协议和B/S 结构 1.2 前端三大核心技术 1.2.1 HTML 1.2.2 CSS&#xff08;Cascading Style Sheets&#xff09;层叠样式表 1.2.3 JavaScript 二、tomcat的功能介绍 2.1 安装 tomcat 环境准备 2.1.1 安装java环境 2.1.2 安装并启动tomcat …

vscode提升:JSON 中不允许有注释

解决方案 &#xff1a; 运行&#xff1a; json with comment 参考链接&#xff1a; https://blog.csdn.net/eqizhihui/article/details/134014010 人工智能学习网站 https://chat.xutongbao.top

基于飞腾平台的Hbase的安装配置

【写在前面】 飞腾开发者平台是基于飞腾自身强大的技术基础和开放能力&#xff0c;聚合行业内优秀资源而打造的。该平台覆盖了操作系统、算法、数据库、安全、平台工具、虚拟化、存储、网络、固件等多个前沿技术领域&#xff0c;包含了应用使能套件、软件仓库、软件支持、软件适…

iOS Native与JS通信:JSBridge

文章目录 一、简介二、JS 调用 Native1.使用 URL Schemea.UIWebViewb.WKWebView 2.使用 JavaScriptCore (iOS 7)3.使用 WKWebView 和 WKScriptMessageHandler (iOS 8) 三、Native 调用 JS1.使用 UIWebView2.使用 WKWebView3.使用 JavaScriptCore (iOS 7) 一、简介 对于移动应用…

深入浅出:你需要了解的用户数据报协议(UDP)

文章目录 **UDP概述****1. 无连接性****2. 尽最大努力交付****3. 面向报文****4. 多种交互通信支持****5. 较少的首部开销** **UDP报文的首部格式****详细解释每个字段** **UDP的多路分用模型****多路分用的实际应用** **检验和的计算方法****伪首部的详细内容****检验和计算步…

Python 数据分析之Numpy学习(一)

Python 数据分析之Numpy学习&#xff08;一&#xff09; 一、Numpy的引入 1.1 矩阵/向量的按位运算 需求&#xff1a;矩阵的按位相加 [0,1,4] [0,1,8] [0,2,12] 1.1.1 利用python实现矩阵/向量的按位运算 # 1.通过列表实现 list1 [0, 1, 4] list2 [0, 1, 8]# 列表使用…

iOS 18 Beta 5:苹果的细腻之笔,绘制用户体验新画卷

在苹果的世界里&#xff0c;每一次系统更新都是对用户体验进行的一次精心雕琢。 随着iOS 18 Beta 5的上线&#xff0c;苹果带来了一系列令人耳目一新的功能&#xff0c;同时也在系统的每个细微之处展现了对完美的追求。 Safari浏览器的“干扰控制”功能 在今天信息充斥的数字…

SpringBoot接入高德地图猎鹰轨迹服务API

SpringBoot接入高德地图猎鹰轨迹服务API 一、AP文档 猎鹰轨迹服务API文档 二、页面图 1、需登录账号&#xff0c;申请对应的应用key值 三、代码部分&#xff1a; 1、控制层 RestController RequestMapping("/gdTrack") public class TrackController {private …

搜维尔科技:【研究】Haption Virtuose外科手术触觉视觉学习系统的开发和评估

Haption面临挑战 除此之外&#xff0c;外科医生有时会对骨组织进行非常复杂的手术&#xff0c;其中一个例子是人工耳蜗的手术植入。重要的是要避免神经或血管等危险结构受伤&#xff0c;并尽可能轻柔地进行手术。在外科医生能够安全、无差错地进行此类手术之前&#xff0c;需要…

Flink常见数据源使用教程(DataStream API)

前言 一个 Flink 程序,其实就是对 DataStream 的各种转换。具体来说,代码基本上都由以下几部分构成,如下图所示: 获取执行环境(execution environment)读取数据源(source)定义基于数据的转换操作(transformations)定义计算结果的输出位置(sink)触发程序执行(exec…

鸿蒙HarmonOS实战开发: CMake脚本编写构建NDK工程

NDK工程构建 HarmonyOS NDK默认使用CMake作为构建系统&#xff0c;随包提供了符合HarmonyOS工具链的基础配置文件ohos.toolchain.cmake&#xff0c;用于预定义CMake变量来简化开发者配置。 常用的NDK工程构建方式有&#xff1a; 从源码构建 源码构建也有不同方式&#xff1a;…

写给大模型新人的经验,刷到少走三年弯路!

这篇文章&#xff0c;我将结合自己在大模型领域的经验&#xff0c;给大家详细聊聊新人应该如何转行大模型赛道&#xff1f; 比如大模型都有哪些方向&#xff1f;各方向的能力要求和岗位匹配&#xff1f;新手转行大模型常踩的坑和常见的误区&#xff1f;以及入行大模型最顺滑的…

什么是HW,企业要通过什么方式进行HW安全保障?

一、什么是HW 网络安全形势近年出现新变化&#xff0c;网络安全态势变得越来越复杂&#xff0c;黑客攻击入侵、勒索病毒等网络安全事件愈演愈烈&#xff0c;严重威胁到我国的网络空间安全。同时&#xff0c;国内不少关键信息基础设施的建设管理单位安全意识不够、安全投入不足…

怎么管控终端电脑上的移动端口

管控终端电脑上的移动端口&#xff0c;尤其是USB等移动端口&#xff0c;是确保企业数据安全和提升网络管理效率的重要手段。 一、使用注册表编辑器禁用USB端口&#xff08;适用于Windows系统&#xff09; 打开注册表编辑器&#xff1a; 同时按下“WinR”组合键&#xff0c;打…

24年上半年天融信营收缩减1.8亿,亏损2.06亿

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330#rd 《网安面试指南》http://mp.weixin.qq.com/s?…