Java中的网络编程------基于Socket的TCP编程和基于UDP的网络编程,netstat指令

Socket

在Java中,Socket是一种用于网络通信的编程接口,它允许不同计算机之间的程序进行数据交换和通信。Socket使得网络应用程序能够通过TCP或UDP协议在不同主机之间建立连接、发送数据和接收数据。以下是Socket的基本介绍:

  • Socket类型:在Java中,有两种主要类型的Socket,分别用于不同类型的通信协议:

  • TCP Socket:使用TCP协议进行通信,提供可靠的、面向连接的数据传输。TCP Socket使用Socket类进行创建和管理。

  • UDP Socket:使用UDP协议进行通信,提供不可靠的、面向无连接的数据传输。UDP Socket使用DatagramSocket类进行创建和管理。

  • 套接字连接Socket允许两台计算机之间建立连接,一台计算机充当服务器,另一台计算机充当客户端服务器Socket等待客户端连接请求,客户端Socket通过指定服务器地址和端口号来连接服务器。客户端和服务器端都有Socket,是两台机器通信的端点

  • 通信协议:Socket可以使用不同的通信协议,最常见的是TCP和UDP。TCP提供可靠的、面向连接的通信,确保数据按顺序到达和错误处理。UDP提供不可靠的、面向无连接的通信,适用于低延迟应用。

  • 数据传输Socket允许应用程序通过输入和输出流(InputStream和OutputStream)进行数据传输。应用程序可以使用这些流发送和接收数据。

  • 阻塞和非阻塞模式:Socket可以以阻塞或非阻塞模式工作。在阻塞模式下,Socket操作将等待直到完成,而在非阻塞模式下,Socket操作可以立即返回。

  • 安全性:Socket通信可以通过安全套接字层(SSL)或传输层安全性(TLS)来加密,以提供数据的保密性和完整性。

TCP网络通信编程

TCP(传输控制协议)是一种可靠的、面向连接的网络通信协议,它用于在计算机网络上可靠地传输数据。TCP通信是客户端-服务器模型的基础,它确保了数据的可靠性和有序性。以下是TCP网络通信编程的基本介绍:

  1. 面向连接:TCP是一种面向连接的协议,通信的两端(客户端和服务器)在开始通信之前必须建立连接。连接建立后,数据可以在两端之间可靠地传输。

  2. 可靠性:TCP提供可靠的数据传输。它使用确认机制来确保数据的完整性和有序性。如果接收方收到数据,它会发送一个确认(ACK)给发送方,如果发送方没有收到确认,它会重新发送数据。

  3. 有序性:TCP保证数据按发送的顺序到达接收方。即使数据包在传输过程中可能以不同的顺序到达,TCP会重新排列它们,以确保接收方按正确的顺序接收数据。

  4. 流式数据传输:TCP提供了流式数据传输,数据被视为连续的字节流,而不是分成离散的数据包。这使得TCP适用于传输大文件和多媒体数据。

  5. 双向通信:TCP连接是全双工的,允许双方同时发送和接收数据。客户端和服务器都可以发送请求和响应。

  6. 端口号:TCP通信使用端口号来标识不同的服务或应用程序。服务器应用程序通常监听特定端口,客户端通过指定目标主机和端口来连接到服务器。

  7. 阻塞式通信:TCP通信默认是阻塞的,这意味着发送和接收数据的操作会一直阻塞,直到完成。这可以通过多线程或非阻塞I/O来处理,以确保应用程序的响应性。

  8. 安全性:TCP通信可以通过安全套接字层(SSL)或传输层安全性(TLS)来加密,以提供数据的保密性和完整性。

在这里插入图片描述

在Java中,你可以使用java.net包中的SocketServerSocket类来实现TCP网络通信。客户端使用Socket类来建立与服务器的连接,而服务器使用ServerSocket类来监听客户端连接请求。以下是一些简单的Java TCP服务器和客户端的示例,以便更好地理解TCP通信的基本原理:

1.使用字节流的方式发送数据和接收数据

服务器端代码

public class Server {public static void main(String[] args) throws IOException {//1. 在本机 的 9999 端口监听, 等待连接// 细节: 要求在本机没有其它服务在监听 9999,客户端的端口号只能被一个服务监听// 细节:这个 ServerSocket 可以通过 accept() 返回多个 Socket[多个客户端连接服务器的并发]ServerSocket serverSocket = new ServerSocket(9999);System.out.println("服务端,在 9999 端口监听,等待连接..");//2. 当没有客户端连接 9999 端口时,程序会 阻塞, 等待连接// 如果有客户端连接,则会返回 Socket 对象,程序继续Socket socket = serverSocket.accept();//3.从一个已建立的网络套接字(Socket)中获取输入流,以便从该套接字接收数据InputStream inputStream = socket.getInputStream();//4.通过输入流从网络套接字中读取数据byte[] buf = new byte[1024];int readLen = 0;while ((readLen = inputStream.read(buf)) != -1) {System.out.println(new String(buf,0,readLen));}//5.从一个已建立的网络套接字(Socket)中获取输出流,以便将数据发送到该套接字OutputStream outputStream = socket.getOutputStream();//6.通过输出流 (outputStream) 发送内容到网络套接字outputStream.write("hello,client".getBytes());//7.设置结束标记。用于关闭套接字(Socket)的输出流。具体来说,它关闭套接字的输出流,表示在此之后不再发送数据到套接字的另一端socket.shutdownOutput();//8.关闭流和 socketinputStream.close();outputStream.close();socket.close();serverSocket.close();}
}

客户端代码

public class Client {public static void main(String[] args) throws IOException {//1. 连接服务端 (ip , 端口)//连接本机的 9999 端口, 如果连接成功,返回 Socket 对象Socket socket = new Socket(InetAddress.getLocalHost(),9999);//2.从一个已建立的网络套接字(Socket)中获取输出流,以便将数据发送到该套接字OutputStream outputStream = socket.getOutputStream();//3.通过输出流 (outputStream) 发送内容到网络套接字outputStream.write("hello,server".getBytes());//4.设置结束标记。用于关闭套接字(Socket)的输出流。具体来说,它关闭套接字的输出流,表示在此之后不再发送数据到套接字的另一端socket.shutdownOutput();//5.从一个已建立的网络套接字(Socket)中获取输入流,以便从该套接字接收数据InputStream inputStream = socket.getInputStream();//6.通过输入流从网络套接字中读取数据byte[] buf = new byte[1024];int readLen = 0;while ((readLen = inputStream.read(buf)) != -1){System.out.println(new String(buf,0,readLen));}//7.关闭流和 socketoutputStream.close();inputStream.close();socket.close();System.out.println("客户端退出");}
}

2.使用字符流的方式发送数据和接收数据
服务器端代码

public class Server {public static void main(String[] args) throws IOException {//1. 在本机 的 9999 端口监听, 等待连接// 细节: 要求在本机没有其它服务在监听 9999,客户端的端口号只能被一个服务监听// 细节:这个 ServerSocket 可以通过 accept() 返回多个 Socket[多个客户端连接服务器的并发]ServerSocket serverSocket = new ServerSocket(9999);System.out.println("服务端,在 9999 端口监听,等待连接..");//2. 当没有客户端连接 9999 端口时,程序会 阻塞, 等待连接// 如果有客户端连接,则会返回 Socket 对象,程序继续Socket socket = serverSocket.accept();//3.从一个已建立的网络套接字(Socket)中获取输入流,以便从该套接字接收数据InputStream inputStream = socket.getInputStream();//4.将字节流转换为字符流InputStreamReader inputStreamReader = new InputStreamReader(inputStream);//5.对字符流进行包装,提供了更方便的读取方法,如readLine()可以一次读取一行数据BufferedReader bufferedReader = new BufferedReader(inputStreamReader);//6.通过输入流从网络套接字中读取数据String line = "";while ((line = bufferedReader.readLine()) != null) {System.out.println(line);}//7.从一个已建立的网络套接字(Socket)中获取输出流,以便将数据发送到该套接字OutputStream outputStream = socket.getOutputStream();//8.将字节流转换为字符流OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);//9.对字符流进行包装,提供了更方便的写入方法,如writer()可以直接写入字符串而不用转换为字符数组BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);//10.通过输出流发送内容到网络套接字bufferedWriter.write("hello,client");//11.当我们使用缓冲写入数据时,数据会先被写入到缓冲区中,而不是直接写入到目标文件或流中。// 调用flush()方法会强制将缓冲区中的数据立即写入到目标文件或流中,确保数据的及时更新。// 这样可以避免数据在缓冲区中滞留而没有被写入到目标文件或流中的情况发生。bufferedWriter.flush();//12.设置结束标记。用于关闭套接字(Socket)的输出流。具体来说,它关闭套接字的输出流,表示在此之后不再发送数据到套接字的另一端socket.shutdownOutput();//13.关闭流和 socketbufferedReader.close();bufferedWriter.close();socket.close();serverSocket.close();}
}

客户端代码

public class Client {public static void main(String[] args) throws IOException {//1. 连接服务端 (ip , 端口)//连接本机的 9999 端口, 如果连接成功,返回 Socket 对象Socket socket = new Socket(InetAddress.getLocalHost(),9999);//2.从一个已建立的网络套接字(Socket)中获取输出流,以便将数据发送到该套接字OutputStream outputStream = socket.getOutputStream();//3.将字节流转换为字符流OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);//4..对字符流进行包装,提供了更方便的写入方法,如如writer()可以直接写入字符串而不用转换为字符数组BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);//5.通过输出流发送内容到网络套接字bufferedWriter.write("hello,server");//6.当我们使用缓冲写入数据时,数据会先被写入到缓冲区中,而不是直接写入到目标文件或流中。// 调用flush()方法会强制将缓冲区中的数据立即写入到目标文件或流中,确保数据的及时更新。// 这样可以避免数据在缓冲区中滞留而没有被写入到目标文件或流中的情况发生。bufferedWriter.flush();//需要刷新否则写不进去//7.设置结束标记。用于关闭套接字(Socket)的输出流。具体来说,它关闭套接字的输出流,表示在此之后不再发送数据到套接字的另一端socket.shutdownOutput();//8.从一个已建立的网络套接字(Socket)中获取输入流,以便从该套接字接收数据InputStream inputStream = socket.getInputStream();//9.将字节流转换为字符流InputStreamReader inputStreamReader = new InputStreamReader(inputStream);//10.对字符流进行包装,提供了更方便的读取方法,如readLine()可以一次读取一行数据BufferedReader bufferedReader = new BufferedReader(inputStreamReader);//11.通过输入流从网络套接字中读取数据String line = "";while ((line = bufferedReader.readLine()) != null) {System.out.println(line);}//12.关闭流和 socketbufferedWriter.close();bufferedReader.close();socket.close();System.out.println("客户端退出");}
}

3.发送图片的代码:
服务器端代码

public class Server {public static void main(String[] args) throws Exception {ServerSocket serverSocket = new ServerSocket(6666);System.out.println("服务端,在 6666 端口监听,等待连接..");Socket socket = serverSocket.accept();//通过将socket的输入流包装在BufferedInputStream中,可以在读取数据时先将数据存储在缓冲区中,// 然后再从缓冲区中读取数据,减少了直接从输入流中读取数据的次数,提高了读取数据的效率。//当然可以不用缓冲流也是可以的,但是效率不高,最好还是用缓冲流BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);String descFile = "src\\main\\java\\com\\example\\retcode\\test\\net\\socket\\tcp\\tcp4\\线程状态.bmp";BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(descFile));bufferedOutputStream.write(bytes);bufferedOutputStream.close();//通过 socket 获取到输出流(字符)BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));bufferedWriter.write("收到图片");bufferedWriter.flush();socket.shutdownOutput();bufferedOutputStream.close();bufferedInputStream.close();bufferedWriter.close();socket.close();}
}

客户端代码

public class Client {public static void main(String[] args) throws Exception {Socket socket = new Socket(InetAddress.getLocalHost(),6666);String filePath = "d:\\线程状态.bmp";BufferedInputStream bufferedInputStream  = new BufferedInputStream(new FileInputStream(filePath));byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);OutputStream outputStream = socket.getOutputStream();BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);bufferedOutputStream.write(bytes);socket.shutdownOutput();BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));String line ="";while ((line = bufferedReader.readLine())!=null){System.out.println(line);}bufferedOutputStream.close();bufferedInputStream.close();bufferedReader.close();socket.close();System.out.println("客户端退出");}
}

StreamUtils类:

public class StreamUtils {/*** 功能:将输入流转换成byte[], 即可以把文件的内容读入到byte[]* @param is* @return* @throws Exception*/public static byte[] streamToByteArray(InputStream is) throws Exception{ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象byte[] b = new byte[1024];//字节数组int len;while((len=is.read(b))!=-1){//循环读取bos.write(b, 0, len);//把读取到的数据,写入bos	}byte[] array = bos.toByteArray();//然后将bos 转成字节数组bos.close();return array;}/*** 功能:将InputStream转换成String* @param is* @return* @throws Exception*/public static String streamToString(InputStream is) throws Exception{BufferedReader reader = new BufferedReader(new InputStreamReader(is));StringBuilder builder= new StringBuilder();String line;while((line=reader.readLine())!=null){builder.append(line+"\r\n");}return builder.toString();}}

netstat指令

netstat 是一个用于显示网络连接和路由表信息的命令行工具,它可以在不同的操作系统中使用,包括Windows、Linux和macOS。netstat 可以帮助你监视和诊断网络连接问题,了解网络活动情况。以下是 netstat 命令的基本介绍:

在命令行中执行 netstat 命令时,通常需要提供一些选项和参数以获取特定的网络信息。以下是一些常见的 netstat 选项和用法:

  1. 查看所有活动连接

    netstat -a
    

    这会显示所有的活动网络连接,包括TCP和UDP连接,以及监听中的端口。

  2. 查看活动TCP连接

    netstat -at
    

    这会显示所有的活动TCP连接,包括本地地址、远程地址、状态等信息。

  3. 查看活动UDP连接

    netstat -au
    

    这会显示所有的活动UDP连接,包括本地地址、远程地址等信息。

  4. 显示监听端口

    netstat -l
    

    这会显示当前正在监听的端口,包括TCP和UDP。

  5. 显示路由表信息

    netstat -r
    

    这会显示操作系统的路由表信息,包括网络地址、网关、接口等。

  6. 显示统计信息

    netstat -s
    

    这会显示各种协议的统计信息,如TCP、UDP、ICMP等。

  7. 显示PID和程序名

    netstat -b
    

    这会显示每个连接的相关进程的PID和程序名。在Windows系统中,需要以管理员权限运行才能查看程序名。

  8. 显示数字格式

    netstat -n
    

    这会以数字格式显示网络地址和端口,而不是尝试解析主机名和服务名。

这只是 netstat 命令的一些常见选项和用法。根据你的需求,你可以根据操作系统和情况选择不同的选项以查看所需的网络信息。netstat 是网络管理和故障排除的有用工具,它可以帮助你了解网络连接、端口使用情况、路由信息等,以便更好地管理和维护计算机网络。

UDP编程

UDP(User Datagram Protocol,用户数据报协议)是一种无连接的、不可靠的网络通信协议,它用于在计算机网络上进行数据传输。UDP通信的特点是速度快,但不保证数据的可靠性。以下是Java中UDP编程的基本介绍:

  1. 无连接性:UDP是无连接的协议,通信双方在发送和接收数据之前不需要建立连接。这使得UDP通信的速度较快,因为不需要进行连接和断开的握手过程。

  2. 不可靠性:UDP不保证数据的可靠性,数据包可能会丢失、乱序到达或重复到达。因此,如果需要可靠的数据传输,必须在应用层进行额外的处理。

  3. 面向数据报:UDP通信是面向数据报的,每个UDP数据包都是独立的,没有关联性。这使得应用程序可以发送和接收独立的消息。

  4. 低开销:由于UDP没有建立连接和维护状态的开销,因此它在某些情况下比TCP更高效。UDP通常用于实时音频、视频和在线游戏等需要快速传输数据的应用。

  5. 广播和多播:UDP支持广播和多播,允许一个主机向多个接收者发送相同的数据包,而无需建立多个连接。

在Java中,你可以使用java.net包中的DatagramSocketDatagramPacket类来实现UDP编程。以下是基本的UDP编程步骤:

发送端(客户端)

  1. 创建一个DatagramSocket对象,用于发送数据。
  2. 创建一个DatagramPacket对象,将要发送的数据放入其中,并指定目标主机的IP地址和端口号。
  3. 使用DatagramSocketsend()方法发送数据包。
  4. 关闭DatagramSocket以释放资源。

接收端(服务器端)

  1. 创建一个DatagramSocket对象,用于接收数据,并指定监听的端口号。
  2. 创建一个DatagramPacket对象,用于接收数据。
  3. 使用DatagramSocketreceive()方法接收数据包。
  4. 从接收到的数据包中提取数据。
  5. 关闭DatagramSocket以释放资源。

以下是一个简单的UDP发送端和接收端的示例:

发送端代码

public class UDPSender {public static void main(String[] args) throws IOException {//1.创建 DatagramSocket 对象,准备在 9998 端口 接收数据DatagramSocket socket = new DatagramSocket(9998);//2. 将需要发送的数据,封装到 DatagramPacket 对象byte[] data = "hello 明天吃火锅~".getBytes();//说明: 封装的 DatagramPacket 对象 data 内容字节数组 , data.length , 主机(IP) , 端口DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("172.21.10.13"), 9999);socket.send(packet);//3.=== 接收从 A 端回复的信息//(1) 构建一个 DatagramPacket 对象,准备接收数据// 在前面讲解 UDP 协议时,一个数据包最大 64kbyte[] data1 = new byte[1024];DatagramPacket packet1 = new DatagramPacket(data1, data1.length);//(2) 调用 接收方法, 将通过网络传输的 DatagramPacket 对象// 填充到 packet 对象//当有数据包发送到 本机的 9998 端口时,就会接收到数据// 如果没有数据包发送到 本机的 9998 端口, 就会阻塞等待. socket.receive(packet);socket.receive(packet1);//(3) 可以把 packet 进行拆包,取出数据,并显示. int length = packet.getLength();//实际接收到的数据字节长度int length = packet1.getLength();data1 = packet1.getData();//接收到数据String s = new String(data1, 0, length);System.out.println(s);//关闭资源socket.close();System.out.println("B 端退出");}
}

接收端代码

public class UDPReceiver {public static void main(String[] args) throws IOException {//1. 创建一个 DatagramSocket 对象,准备在 9999 接收数据System.out.println("9999端口等待数据的请求");DatagramSocket socket = new DatagramSocket(9999);//2. 构建一个 DatagramPacket 对象,准备接收数据// 在前面讲解 UDP 协议时,老师说过一个数据包最大 64kbyte[] buf = new byte[1024];DatagramPacket packet = new DatagramPacket(buf, buf.length);//3. 调用 接收方法, 将通过网络传输的 DatagramPacket 对象// 填充到 packet 对象// 当有数据包发送到 本机的 9999 端口时,就会接收到数据// 如果没有数据包发送到 本机的 9999 端口, 就会阻塞等待. System.out.println("接收端 A 等待接收数据..");socket.receive(packet);//4. 可以把 packet 进行拆包,取出数据,并显示. int length = packet.getLength();//实际接收到的数据字节长度int length = packet.getLength();byte[] data = packet.getData();//接收到数据String s = new String(data, 0, length);System.out.println(s);//===回复信息给 B 端//将需要发送的数据,封装到 DatagramPacket 对象byte[] data1 = "好的, 明天见".getBytes();//说明: 封装的 DatagramPacket 对象 data 内容字节数组 , data.length , 主机(IP) , 端口DatagramPacket packet1 = new DatagramPacket(data1, data1.length, InetAddress.getByName("172.21.10.13"), 9998);socket.send(packet1);//发送//5. 关闭资源socket.close();System.out.println("A 端退出...");}
}

UDP通信适用于需要快速传输数据且可以容忍一些数据丢失的场景,例如实时音视频传输和在线游戏。然而,由于UDP不保证数据的可靠性,因此在应用中需要考虑如何处理丢失的数据或保证数据的顺序。

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

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

相关文章

后端笔试题(2)分频器波形图

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口

冠达管理:“旺季”来临,煤炭板块走高,云煤能源、陕西黑猫涨停

煤炭板块1日盘中发力走高,截至发稿,云煤动力、陕西黑猫涨停,兖矿动力涨超7%,晋控煤业、华阳股份涨超6%,山西焦煤、平煤股份涨超5%。 组织表明,动力大通胀背景下,未来3-5年煤炭供需偏紧的格局仍…

【Spring】SpringBoot的10个参数验证技巧

这里写目录标题 前言1.使用验证注解2 使用自定义验证注解3 在服务器端验证4 提供有意义的错误信息5 将 i18n 用于错误消息messages.properties6 使用分组验证7 对复杂逻辑使用跨域验证8 对验证错误使用异常处理9 测试你的验证逻辑10 考虑客户端验证总结 前言 参数验证很重要&am…

mysql-1:认识mysql

文章目录 数据库概述什么是数据库什么是关系型数据库 MySQL的概述MySQL是什么MySQL发展历程 SQL的概述什么是SQLSQL发展的简要历史:SQL语言分类 数据库概述 什么是数据库 数据库就是[存储数据的仓库],其本质是一个[文件系统],数据按照特定的…

简述电子企业MES管理系统解决方案的实施策略

引言:在电子制造企业中,随着产品种类的增多和订单数量的增长,传统的手工管理方式已经无法满足企业的生产需求。为了提高生产效率,降低成本,提高订单的履行速度和准确性,电子企业需要实施MES管理系统。本文将…

VGA OUT 的PCB设计注意事项

VGA(Video Graphics Array)即视频图形阵列,具有分辨率高、显示速率快、颜色丰富等优点。VGA接口不但是CRT显示设备的标准接口,同样也是LcD液晶显示设备的标准接口,具有广泛的应用范围。 VGA OUT PCB设计注意事项: 1、整体布局时&…

混合动力汽车耐久测试

一 背景 整车厂可通过发动机和电机驱动的结合为多款车型提供混合动力驱动技术。汽车集成电机驱动可大大减少二氧化碳的排放,不仅如此,全电动驱动或混合动力驱动的汽车还将使用户体验到更好的驾驶感受,且这种汽车可通过电动机来实现更快的加速…

Jenkins java8安装版本安装

一、首先准备Jenkins、Jdk8、Tomcat9安装包 根据Jenkins官网介绍,Jenkins支持Java8的版本如下: 我们选择2.164版本进行安装,根据版本号支持输入下载地址:https://archives.jenkins.io/war/2.164/jenkins.war,进行下载…

XSS简单介绍

目录 一、认识XSS 1.XSS原理 2.XSS分类 二、XSS漏洞复现 1.搭建靶机进行复现 2.案例解析 2.1第一关 2.2第二关 2.3第三关 2.4第四关 一、认识XSS 1.XSS原理 XSS跨站脚本攻击是指恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,…

skywalking springgateway 全链路

环境 spring-cloud-gateway 3.1.0 springGateway整合skywalking skywalking 默认是不整合springGateway的,需要手动拷贝skywalking optional-plugins下的 apm-spring-cloud-gateway-N.x-plugin-8.13.0.jar 和 apm-spring-webflux-5.x-plugin-8.13.0.jar 架包拷贝到plugins目…

C# 采用3DES-MAC进行签名 base64解码与编码

** 3DES-MAC ** 3DES-MAC(Triple Data Encryption Standard Message Authentication Code)是一种消息认证码(MAC)算法,用于验证消息的完整性和真实性。3DES-MAC使用了3DES(Triple Data Encryption Standa…

将 Python 与 RStudio IDE 配合使用(R与Python系列第一篇)

目录 前言: 1-安装reticulate包 2-安装Python 3-选择Python的默认版本(配置Python环境) 4-使用Python 4.1 运行一个简单的Python脚本 4.2 在RStudio上安装Python模块 4.3 在 R 中调用 Python 模块 4.4 在RStudio上调用Python脚本写的…

python-wordcloud词云

导入模块 from wordcloud import WordCloud import jieba import imageio import matplotlib.pyplot as plt from PIL import ImageGrab import numpy as npwordcloud以空格为分隔符号,来将文本分隔成单词 PIL pillow模块 img imageio.imread(image.png)这行代码…

PHP8的多维数组-PHP8知识详解

今天分享的是php8的数组中的多维数组,主要内容有:多维数组的概念、创建和输出二维数组、创建和输出三维数组。 1、多维数组的概念 多维数组是包含一个或多个数组的数组。在多维数组中,主数组中的每一个元素也可以是一个数组,子数…

c语言开篇---跟着视频学C语言

标识符 标识符必须声明定义,可以是变量、函数或其他实体。 Int是标识符吗? 不是,int是c语言关键词,不是随意命名的 C语言关键词如下: 常量 不需要被声明,不能赋值更改。 printf函数 printf是由print打印…

CH341 USB总线转接芯片

产品概述: CH341是一个USB总线的转接芯片,通过USB总线提供异步串口、打印口、并口以及常用的2线和4线等同步串行接口。 在异步串口方式下,CH341提供串口发送使能、串口接收就绪等交互式的速率控制信号以及常用的MODEM联络信号,用于…

QT中闹钟的设置

.h文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> //按钮 #include <QTextEdit> //文本 #include <QLabel> //标签 #include <QLineEdit> //行编辑器#include <QTimerEvent> //定时器事件类头文件 #…

【51单片机实验笔记】声学篇(一) 蜂鸣器基本控制

目录 前言硬件介绍PWM基础蜂鸣器简介 原理图分析蜂鸣器驱动电路 软件实现蜂鸣器短鸣蜂鸣器功能封装 总结 前言 蜂鸣器在生活中的应用实则相当广泛。通过本章你将学会制造噪声 &#xff08;笑~&#xff09;你将学会驱动它们&#xff0c;并发出响声。 硬件介绍 PWM基础 占空比…

高德Android高性能高稳定性代码覆盖率技术实践

前言 代码覆盖率(Code coverage)是软件测试中的一种度量方式&#xff0c;用于反映代码被测试的比例和程度。 在软件迭代过程中&#xff0c;除了应该关注测试过程中的代码覆盖率&#xff0c;用户使用过程中的代码覆盖率也是一个非常有价值的指标&#xff0c;同样不可忽视。因为…

java八股文面试[java基础]——字节码的组成

什么是字节码&#xff1f; 因为JVM针对各种操作系统和平台都进行了定制&#xff0c;无论在什么平台&#xff0c;都可以通过javac命令将一个.java文件编译成固定格式的字节码&#xff08;.class文件&#xff09;供JVM使用。之所以被称为字节码&#xff0c;是因为.class文件是由…