当前位置: 首页 > news >正文

【网络编程】TCP数据流套接字编程

目录

一. TCP API 

二. TCP回显服务器-客户端

1. 服务器

2. 客户端

3. 服务端-客户端工作流程

4. 服务器优化


TCP数据流套接字编程是一种基于有连接协议的网络通信方式


一. TCP API 

在TCP编程中,主要使用两个核心类ServerSocket Socket


ServerSocket

ServerSocket类只有服务器会使用,用于接受连接

ServerSocket构造方法:

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

 ServerSocket方法:

方法签名方法说明
Socket accept()

监听端口,如果有客户端连接后,则会返回一个服务端 Socket 对象

如果没有客户端连接,则会进入阻塞等待

void close()关闭此套接字
  •  accept()方法用于接收客户端连接请求并建立正式通信通道
  •  accept()方法是接受连接并返回Socket,真正和客户端进行交互的是Socket

 Socket

 Socket类负责具体的数据传输 

  • 客户端一开始就使用Socket进行通信(请求由客户端发起)
  • 服务器在接受客户端建立请求后,返回服务端Socket
  • 在双方建立连接之后,都会使用Socket进行通信 

Socket 构造方法:

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

 Socket 方法:

方法签名方法说明
InetAddress getInetAddress()返回的地址(IP和端口)
InputStream getInputStream()返回输入流
OutputStream getOutputStream()返回输出流
  • TCP面向字节流,基本传输单位是字节

二. TCP回显服务器-客户端

回显服务器

回显服务器:不进行任何的业务逻辑,只是将收到的数据显示出来


1. 服务器

  接收连接请求 

  • TCP是有连接的可靠通信
  • 真正建立连接的过程在内核中被实现,应用层只是调用相应API同意建立连接
  • 类比打电话,客户端拨号,服务器这边在响铃,通过调用accept接听

 代码实现:

            Socket clientSocket = serverSocket.accept();
  • accept()方法具有阻塞功能
  • accept()方法一次只能返回一个Socket对象,接收一次请求
  • 如果没有客户端发起连接请求,则会进入阻塞等待
  • 如果有一个客户端发起连接请求,则执行一次,如果有多个客户端发起连接请求,则执行多次

处理请求

 private void processConnection(Socket clientSocket) {}
  •  使用方法专门处理一次连接,在一次连接中可能会涉及多次请求响应交互

如何处理请求和返回响应? 

由于TCP面向字节流,我们可以字节流传输的类 InputStream和OutputStream

   try(InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()){} catch (IOException e) {throw new RuntimeException(e);}
  •  使用try-with-resources管理InputStream和OutputStream,确保流自动关闭。 
  • InputStream从网卡中读取数据
  • OutputStream从网卡中写入数据

1)接收请求并解析

        Scanner scanner = new Scanner(inputStream);if(!scanner.hasNext()){System.out.printf("[客户端ip:%s,端口号:%d],客户端下线\n",clientSocket.getInetAddress(),clientSocket.getPort());break;}String request = scanner.next();
  • 客户端和服务器双方都有自己的缓冲区
  • 客户端发送数据,会先将数据放入服务器缓冲区中
  • 如果服务器缓冲区中没有数据,hasNext()则会陷入阻塞等待中
  • 如果客户端退出,则会触发四次挥手断开连接,服务器会感知到,就会在hasNext()返回false。

2)根据请求计算响应

 回显服务器:不会处理数据,输入什么就会返回什么

            String response = process(request);

使用process方法来实现回显功能

    public  String process(String request) {return request;}

 如果想要实现特定的功能,直接在process中实现即可 

3)返回响应

 Scanner的写操作无法自己完成,只能进行读取操作,写操作需要依靠其他的类(PrintWriter) 

                PrintWriter printWriter = new PrintWriter(outputStream);
//                将数据写入数据的缓冲区中printWriter.println(respond);

冲刷缓冲区

 由于缓冲区的特殊机制,缓冲区只有满的时候,才会被发送出去

                printWriter.flush();
  • 我们这里要保证实时性,客户端每发送一次请求,服务器都要第一时间响应
  • IO操作比较低效,如果每进行一次IO,就要冲刷一次,效率很低,为了让这种低效的操作少一点,等缓冲区满了,才会冲刷

服务器总代码:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TcpEchoServer {private ServerSocket serverSocket = null;TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}public void start() throws IOException {System.out.println("服务器启动");while(true){//从缓冲区内取出并同意链接//将取出的数据使用clientSocket另外保存起来,//每有一个客户端,就会出现一个clientSocket对象,所有使用完,必须关闭Socket clientSocket = serverSocket.accept();//进行数据分析/*            Thread t = new Thread(()->{processConnection(clientSocket);});t.start();*/
//            这样写开销大,会有很多次的创建和销毁,改进使用线程池ExecutorService service = Executors.newFixedThreadPool(3);service.submit(()->{processConnection(clientSocket);});}}//使用这个方法专门处理一次连接,在一次连接中可能会涉及多次请求交互private void processConnection(Socket clientSocket) {System.out.printf("[客户端ip:%s,端口号:%d],客户端上线\n",clientSocket.getInetAddress(),clientSocket.getPort());//循环处理请求并返回响应(请求可能不止一次)//从网卡中读数据和写数据try(InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()){while (true){
//                byte[] buffer = new byte[1024];
//                int n = inputStream.read(buffer);
//                //将字节数组转换为字符串
//                if(n==-1){
//                    System.out.printf("[客户端ip:%s,端口号:%d],客户端下线",clientSocket.getInetAddress(),clientSocket.getPort());
//                    break;
//                }
//                String request = new String(buffer,0,n);Scanner scanner = new Scanner(inputStream);if(!scanner.hasNext()){System.out.printf("[客户端ip:%s,端口号:%d],客户端下线\n",clientSocket.getInetAddress(),clientSocket.getPort());break;}
//                1.接受请求并解析//客户端必须有一个空格或者换行符String request = scanner.next();
//                2.根据请求计算响应String respond = process(request);
//                3.返回响应//返回的是字节数组类型
//                outputStream.write(request.getBytes(),0,request.getBytes().length);//返回字符串类型(各种类型)PrintWriter printWriter = new PrintWriter(outputStream);
//                将数据写入数据的缓冲区中printWriter.println(respond);//冲刷缓冲区printWriter.flush();//打印日志System.out.printf("[客户端ip:%s,端口号:%d],req:%s,resp:%s\n",clientSocket.getInetAddress(),clientSocket.getPort(),request,respond);}} catch (IOException e) {throw new RuntimeException(e);}finally {try {//必须进行close,clientSocket.close();} catch (IOException e) {throw new RuntimeException(e);}}}private String process(String request) {return request;}public static void main(String[] args) throws IOException {TcpEchoServer server = new TcpEchoServer(9090);server.start();}
}

注意: 

  • 在服务器中,ServerSocket对象不需要被消耗,整个程序中只有一个ServerSocket对象,它的生命周期要伴随整个程序,不能提前关闭,只有程序退出了,才会被释放
  • 方法中的Socket必须要释放,每出现一个客户端,就会随之出现一个Socket对象,如果不释放,Socket对象会越来越多,将文件描述符表占满(内存泄露问题)

2. 客户端

 构造方法

    TcpEchoClient(String serverIp,int serverPort) throws IOException {socket = new Socket(serverIp,serverPort);}
  • 这里不需要将serverIP和serverPort在类中保存
  • 因为tcp有链接,socket会保存好这两个值

客户端如何发送请求和接收响应?

客户端同样使用字节流进行传输

        try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()){} catch (IOException e) {throw new RuntimeException(e);}
  •  使用try-with-resources管理InputStream和OutputStream,确保流自动关闭。 
  • InputStream从网卡中读取数据
  • OutputStream从网卡中写入数据

1)从控制台读取请求

            //客户端输入的数据Scanner scannerConsole = new Scanner(System.in);while(true){System.out.print("->");//客户端没有输入if(!scannerConsole.hasNext()){break;}
//              从控制台读取请求String request = scannerConsole.next();}
  • 使用Scanner进行输入,如果没有输入数据,hasNext()会进入阻塞等待

2)将请求发送给服务器

 Scanner只会读取数据,发送使用类PrintWriter

          PrintWriter writer = new PrintWriter(outputStream);writer.println(request);               
  •  向服务器发送数据

冲刷缓冲区 

                //冲刷缓冲区writer.flush();

将发送的数据,先放入缓冲区中,等待缓冲区满了,才会发送缓冲区中的内容 


3)接收服务器返回的响应

            Scanner scannerNetwork = new Scanner(inputStream);String respond = scannerNetwork.next();
  • 服务器发送的数据,先到达客户端的缓冲区,客户端要从缓冲区读出数据
  • 这里使用Scanner进行读出数据,也可以使用read()方法读取 

4)将响应数据显示在控制台

                System.out.println(respond);

将接收到的字符串响应,直接打印出来即可 


客户端总代码:


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;public class TcpEchoClient {private Socket socket = null;TcpEchoClient(String serverIp,int serverPort) throws IOException {
//        这里不需要将serverIP和serverPort在类中保存
//        因为tcp有链接,socket会保存好这两个值socket = new Socket(serverIp,serverPort);}public void start(){System.out.println("客户端启动");try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()){//客户端输入的数据Scanner scannerConsole = new Scanner(System.in);//通过网络读取Scanner scannerNetwork = new Scanner(inputStream);//像服务器发送请求PrintWriter writer = new PrintWriter(outputStream);while(true){System.out.print("->");//客户端没有输入if(!scannerConsole.hasNext()){break;}
//                1. 从控制台读取请求String request = scannerConsole.next();
//                2.将请求发送给服务端writer.println(request);//冲刷缓冲区writer.flush();
//                3.接受服务端返回的响应//从数据缓冲区中读取出内容String respond = scannerNetwork.next();
//                4.将响应显示在控制台System.out.println(respond);}} catch (IOException e) {throw new RuntimeException(e);}}public static void main(String[] args) throws IOException {TcpEchoClient client = new TcpEchoClient("127.0.0.1",9090);client.start();}
}

3. 服务端-客户端工作流程

 无论是TCP还是UDP都是服务端先启动 

创建连接过程

  1. 服务器启动,由于没有客户端建立连接,accept()进入阻塞,等待客户端创建连接
  2. 客户端启动,客户端申请和服务器建立连接
  3. 服务器从accept()阻塞中返回,调用processConnection()方法进行交互

 双方交互过程

  1. 服务器进入processConnection()方法,执行到hasNext(),由于客户端没有发送数据,服务器读取不到数据,进入阻塞状态
  2. 客户端在hasNext()这里进入阻塞,等待用户在控制台中输入数据
  3. 用户输入数据,客户端从hasNext()中退出阻塞,将数据发送给服务器,next()阻塞等待服务器返回数据
  4. 服务器从hasNext()阻塞中返回,读取请求并处理,构造响应,发送给客户端
  5. 客户端读取响应并打印

4. 服务器优化

            Thread t = new Thread(()->{processConnection(clientSocket);});t.start();
  • 每来一个客户端,服务器就需要创建出一个新的线程
  • 每次客户端结束,服务器就需要销毁这个线程

如果客户端比较多,那么服务器就需要频繁的创建和销毁 ,开销大


 (1)可以通过引入线程池来避免频繁的创建和销毁

            ExecutorService service = Executors.newFixedThreadPool(3);service.submit(()->{processConnection(clientSocket);});

 如果有的客户端处理的过程很短(网站),也有可能客户端处理的时间会很长

处理时间很短的客户端,分配一个专门的线程,有点浪费,所有引入了IO多路复用技术


(2)IO多路复用技术

IO多路复用技术是操作系统提供的机制。 

让一个线程去同时去负责处理多个Socket对象

本质在于这些Socket对象不是同一时刻都需要处理 

虽然有多个Socket对象,但是同一时间活跃的Socket对象只是少数(大部分的Socket对象都是在等数据),我们可以在等的过程中,去处理活跃的Socket对象 


点赞的宝子今晚自动触发「躺赢锦鲤」buff! 

相关文章:

【网络编程】TCP数据流套接字编程

目录 一. TCP API 二. TCP回显服务器-客户端 1. 服务器 2. 客户端 3. 服务端-客户端工作流程 4. 服务器优化 TCP数据流套接字编程是一种基于有连接协议的网络通信方式 一. TCP API 在TCP编程中,主要使用两个核心类ServerSocket 和 Socket ServerSocket Ser…...

数据可视化(Matplotlib和pyecharts)

一 常见图形概念及使用 图表类型适用场景核心特点柱状图(bar)比较不同类别数据(如各地区销售额对比)、时间序列分析(离散时间)高度反映数值大小,支持横向/纵向展示,可叠加分组折线图(plot)连续数据趋势比较(适合展示随时间的变化,如股票价格走势、用户增长趋势)、多变…...

如何系统地入门学习stm32?

如何系统地入门学习stm32? 作为一个在嵌入式领域摸爬滚打十余年的工程师,看到这个问题,我不禁想起自己当年啃着厚重的数据手册,对着一块蓝色的PCB板冥思苦想的日子。STM32的学习之路,说难不算特别难,说简单…...

matlab读取CMEMS海洋温度数据并调整图片的比例

matlab读取CMEMS海洋温度数据并调整图片的比例 matlab读取CMEMS海洋温度数据并调整图片的比例 matlab读取CMEMS海洋温度数据并调整图片的比例 数据的下载见上期: 链接到CMEMS数据下载{python} 本文还会给出另一个关键技巧: 通常设置图片比列直接可以通过…...

ReSearch:基于强化学习的大语言模型推理搜索框架

ReSearch是一种创新性框架,通过强化学习技术训练大语言模型执行"推理搜索",无需依赖推理步骤的监督数据。该方法将搜索操作视为推理链的有机组成部分,其中搜索的时机与方式由基于文本的推理过程决定,而搜索结果进一步引…...

【记录】服务器安装ffmpeg

前言 因为项目中需要用到 ffmpeg 进行图像的一些操作,本文记录下在服务器安装 ffmpeg 的全过程,还是具有一定挑战性的。 系统详情 本文使用的操作系统详情如下 通过 命令 cat /etc/os-release 获取 虽然操作系统为 Rocky Linux,但安装过程是通用的,因为本文记录的是从源代码…...

部署rocketmq集群

容器化部署RocketMQ5.3.1集群 背景: 生产环境单机的MQ不具有高可用,所以我们应该部署成集群模式,这里给大家部署一个双主双从异步复制的Broker集群 一、安装docker yum install -y docker systemctl enable docker --now # 单机部署参考: https://www.cnblogs.com/hsyw/p/1…...

中国AIOps行业分析

基本术语 AIOps是"Artificial Intelligence for IT Operations"(IT运维人工智能)的缩写,它指的是将人工智能技术应用于IT运维领域,基于已有的运维数据(如日志、监控信息、应用信息等),通过机器学习的方式解决自动化运维无法解决的问题6。AIOps将机器学习(ML)…...

C++入门[超详细]

#include <iostream c的标准输入输出流 C的域 using namespace std; namespace本质是一个域 只有域里面的定义代码才能使用 std包含了c输入输出的标准库 缺省 只能从左到右缺省,不能中间空格 void f1(int a10,int b20,int c0) { } f1(); f1(1); f1(1,2); f1(1,2,3); f1(…...

字符串系列一>二进制求和

目录 题目&#xff1a;解析&#xff1a;代码&#xff1a; 题目&#xff1a; 链接: link 解析&#xff1a; 代码&#xff1a; class Solution {public String addBinary(String a, String b) {StringBuffer ret new StringBuffer();int t 0;char[] aa a.toCharArray();char[…...

序列化和反序列化

概念 创建出来的这些对象都存在于JVM中的堆&#xff08;heap&#xff09;内存中&#xff0c;只有JVM处于运行状态的时候&#xff0c;这些对象才可能存在。当JVM停止&#xff0c;这些对象也就随之消失。 java序列化可以帮我们实现&#xff1a;将这些对象持久化&#xff0c;并且…...

rebase和merge的区别

目录 1. ‌合并机制与提交历史‌ 2. ‌冲突处理方式‌ 3. ‌历史追溯与团队协作‌ 4. ‌推荐实践‌ 5. ‌撤销难度‌ git rebase和git merge是Git中两种不同的分支合并策略&#xff0c;核心区别在于提交历史的处理方式&#xff1a;merge保留原始分支结构并生成合并提交&am…...

linux查看目录相关命令

查看目录命令 学习目标 能够使用Linux命令查看目录信息 1. 查看目录命令的使用 命令说明ls查看当前目录信息tree以树状方式显示目录信息 ls命令效果图: tree命令效果图: 2. 查看当前目录路径 命令说明pwd查看当前目录路径 pwd命令效果图: 3. 清除终端内容 命令说明clear…...

203. 移除链表元素

给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5]示例 2&#xff1a; 输入&#xff1a…...

Cursor新版0.49.x发布

小子看到 Cursor 0.49.x 版本正式发布&#xff0c;截止今天已经有两个小patch版本&#xff01;本次更新聚焦于 自动化Rules生成、改进的 Agent Terminal 以及 MCP 图像支持&#xff0c;并带来了一系列旨在提升编码效率和协作能力的改进与修复。 以下是本次更新的详细内容&…...

music21:伍佰 泪桥 MIDI 音乐分析

以下是使用 music21 对伍佰《泪桥》MIDI 音乐进行分析的一些可能方面&#xff1a; 基本信息3 曲长&#xff1a;全曲长 2 分 31 秒。音符数量&#xff1a;共 273 个音符。音轨信息&#xff1a;共 2 个音轨&#xff0c;其中 1 个音轨有音符&#xff0c;可视为单轨 MIDI 文件&am…...

Mybatis源码01-SpringBoot启动时mybatis加载过程

使用了mybatis这么久还没有具体探究了SpringBoot启动时候对于mybatis是怎么加载的。 1、首先项目构建时我们会引入相关的依赖&#xff1a; <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</arti…...

springCloud/Alibaba常用中间件全集(上)

文章目录 SpringCloud:一、Consul:服务注册与发现1、下载Consul2、运行Consul3、服务注册①. 导入依赖②. 配置yml③. 启动类添加Consul的启动服务发现注解④. 解决 **硬编码** 问题⑤. 此时便可以将IP地址改为服务名 4、服务配置与刷新①. 引入Consul-Config依赖②. 修改boots…...

嵌入式单片机通过ESP8266连接物联网实验

第一:通过手机APP远程监控和控制 ESP8266驱动RST低电平触发复位,平时需要跟EN一样分别接10k拉高到3.3V 如果是12E/F的话管脚比较多,GPIO15也要接个1K到地 烧录时GPIO要接地,正常工作时将其拉高或者悬空 主要使用串口通信,烧录固件也是通过串口,烧录时,启动烧录程序后…...

Visio导出清晰图片步骤

在Visio里画完图之后如何导出清晰的图片&#xff1f;&#x1f447; ①左上角单击【文件】 ②导出—更改文件类型—PNG/JPG ③分辨率选择【打印机】&#xff0c;大小选择【源】&#xff0c;即可。 ④选择保存位置并命名 也可以根据自己需要选择是否需要【透明底】哈。 选PNG 然…...

速查手册:TA-Lib 超过150种量化技术指标计算全解 - 1. Overlap Studies(重叠指标)

速查手册&#xff1a;TA-Lib 超过150种量化技术指标计算全解 - 1. Overlap Studies&#xff08;重叠指标&#xff09; TA-Lib&#xff08;Technical Analysis Library&#xff09;是广泛使用的金融技术分析库&#xff0c;实现了超过150种技术指标计算函数&#xff0c;适用于股票…...

大模型Rag - 如何评估Rag

一.RAG流程与评估标准补充 RAG&#xff08;Retrieval-Augmented Generation&#xff09;是一种结合检索与生成的问答架构。为了确保系统效果&#xff0c;需要从以下三个角度对其评估&#xff1a; 回顾RAG流程 用户提出问题 → 系统检索相关上下文 → 基于上下文由大语言模型…...

复习JUC的总结笔记

JUC基础 调用Thread的start方法会调用start0&#xff0c;start0会调用该Thread类的run方法。Thread类如果传入了Runnable&#xff0c;run方法里会调用Runnable的run方法&#xff0c;如果没有传入&#xff0c;则什么也不会做。也可以通过重写Thread的run方法&#xff0c;让start…...

基于MTF的1D-2D-CNN-GRU-Attention时序图像多模态融合的故障识别,适合研究学习(Matlab完整源码和数据),附模型研究报告

基于MTF的1D-2D-CNN-GRU-Attention时序图像多模态融合的故障识别&#xff0c;适合研究学习&#xff08;Matlab完整源码和数据&#xff09;&#xff0c;附模型研究报告 目录 基于MTF的1D-2D-CNN-GRU-Attention时序图像多模态融合的故障识别&#xff0c;适合研究学习&#xff08;…...

5G 毫米波滤波器的最优选择是什么?

新的选择有很多&#xff0c;但到目前为止还没有明确的赢家。 蜂窝电话技术利用大量的带带&#xff0c;为移动用途提供不断增加的带宽。 其中的每一个频带都需要透过滤波器将信号与其他频带分开&#xff0c;但目前用于手机的滤波器技术可能无法扩展到5G所规划的全部毫米波&#…...

构造函数和析构函数

概念&#xff1a;对象的初始化和清理是非常重要的&#xff0c;一个对象在使用之前&#xff0c;需要进行初始化&#xff0c;使用完成后也需要及时清理数据&#xff0c;简单来说构造函数时用来初始化成员属性的&#xff0c;析构函数时用来清理数据的。 C中利用构造函数和析构函数…...

卷积神经网络(CNN)详解

文章目录 引言1.卷积神经网络&#xff08;CNN&#xff09;的诞生背景2.卷积神经网络&#xff08;CNN&#xff09;介绍2.1 什么是卷积神经网络&#xff1f;2.2 卷积神经网络&#xff08;CNN&#xff09;的基本特征2.2.1 局部感知&#xff08;Local Connectivity&#xff09;2.2.…...

NoSQl注入学习

文章目录 什么是NOSQL相关概念数据库文档集合 MongoDB 基础语法创建数据库创建集合插入文档更新文档查询文档 Nosql注入PHP 中的 MongoDB 注入重言式注入联合查询注入JavaScript 注入布尔盲注 Nodejs 中的 MongoDB 注入 从一道题中学习nosql注入 参考&#xff1a; Nosql 注入从…...

借助LlamaIndex实现简单Agent

借助LlamaIndex实现简单Agent 1 简介 智能体的构建发展是一个趋势&#xff0c;借助LlamaIndex简单实现Agent。本文主要借助LlamaIndex中的FunctionTool和Workflow。Workflow是使用事件流的方法实现。 2 构建公共类 由于LlamaIndex中的OpenAI无法直接连接国内大模型&#xf…...

MCGS昆仑通太屏笔记

4.3寸&#xff1a;4013ef/e1 7寸&#xff1a;7032kw 特点&#xff1a; 如果是使用组态屏进行调试使用&#xff0c;选择com1如果是实际项目使用&#xff0c;选择com2 操作步骤&#xff1a; 先创建设备窗口&#xff0c;再创建用户界面 在设备窗口界面&#xff0c;依次设置如下…...

纯FPGA控制AD9361的思路和实现之一 概述

我们知道PS通过内存映射方式方式用户的IP&#xff0c;具体是将用户的逻辑做成AXI_LITE_SALVE外设&#xff0c;PS做为AXI_LITE_MASTER去控制。 在ZYNQ系统中存在PS所以这个架构和思路很流行&#xff0c;ADI出的配置软件无线电子板的DEMO基本都是基于这样的架构。比如下图【上截…...

北斗短报文终端与5G融合:构建空天地海一体化通信新生态

随着北斗三号全球组网完成&#xff0c;短报文通信服务从区域覆盖迈向全球通达&#xff0c;其与5G技术的深度融合&#xff0c;正开创“空天地海一体化”通信新时代。深圳作为全国北斗产业高地&#xff0c;汇聚了遨游通讯等领军企业&#xff0c;其推出的北斗短报文终端通过技术创…...

Meteonorm8-免费使用教程(详细教程-免费)

Meteonorm介绍 Meteonorm 8 是一款专业的气象数据生成软件&#xff0c;广泛应用于太阳能、建筑能效、农业气候研究等领域。它提供全球范围内高精度的气象数据&#xff0c;支持多种数据源和插值方法&#xff0c;帮助用户获取特定地点的长期气象统计信息。 Meteonorm核心功能 …...

nohup的使用

最近远程连接服务器跑程序的时候&#xff0c;总是碰到本地电脑息屏或者ssh断开导致程序中断&#xff0c;往往一觉醒来不是程序跑完了而是因为各种原因本地中断了。为此想到了nohup这个命令&#xff0c;可以让程序在我本地电脑关机后也可以在远端服务器上面运行。 命令如下&…...

如何查看HTTP状态码?

目录 一、HTTP状态码查看方法 1. ​​浏览器开发者工具​​ 2. ​​命令行工具​​ 3. ​​服务器日志分析​​ 二、HTTP状态码分类与核心含义 1. ​​信息类&#xff08;1xx&#xff09;​​ 2. ​​成功类&#xff08;2xx&#xff09;​​ 3. ​​重定向类&#xff08…...

2025.04.19【Chord diagram】| 弦图绘制技巧大全

Customization Apply customization to the circular chart: color, background, track height and more. Chart types Learn how to use other chart types like line chart, barcharts, vertical ablines and more. 文章目录 CustomizationChart types 什么是弦图&#xff…...

解码 Web Service:从技术原理到应用场景的深度剖析

Web Service 是一种基于网络的、分布式的计算技术&#xff0c;它允许不同的应用程序之间通过网络进行通信和交互。以下是关于 Web Service 的详细介绍&#xff1a; 一、定义与概念 Web Service 是一种可以通过 Web 协议&#xff08;如 HTTP&#xff09;进行访问的软件组件&am…...

hackmyvm-airbind

收集信息 arp-scan -l nmap -sS -v 192.168.195.162 访问扫描到的ip&#xff0c;直接跳转到登录页面&#xff0c;利用admin/admin弱口令登录 在settings.php中找到一处文件上传&#xff0c;上传一句话木马&#xff0c;上传成功 反弹shell 上传php-reverse-shell.php 抓包&am…...

[HCIP] OSPF 综合实验

题目 实验需求 1.R5为TSP&#xff0c;其上只能配置IP地址&#xff1b; R5与其他所有直连设备间均使用公有IP&#xff1b;环回地址为100.1.1.1/32 2.R4设备为企业出口路由器 3.整个OSPF环境IP基于172.16.0.0/16划分&#xff1b; 4.所有设备均可访问R5的环回&#xff1b; 5…...

arkTs:使用setTimeout / setInterval 实现透明度切换的轮播图

使用setTimeout / setInterval 实现透明度切换的轮播图 1 主要内容说明1.1 setTimeout1.2 setInterval1.3 表格 2 举例说明2.1 图片变化的内容说明2.2 源码相关内容说明2.3 源码A2.4源码A的运行效果展示2.4.1 效果截图2.4.2 效果视频 3.结语4.定位日期 1 主要内容说明 1.1 set…...

苍穹外卖项目中所涉及到的测试内容

1.使用JWT令牌封装用户令牌&#xff0c;并且设置相应的拦截器校验JWT的有效性&#xff0c;从而确保了项目的安全可靠 1.基本功能测试&#xff1a; 验证合法JWT是否能够正常通过拦截器的校验 验证非法的JWT能否正常通过拦截器的校验 2.可靠性测试&#xff1a; 3.易用性测试 …...

案例驱动的 IT 团队管理:创新与突破之路:第五章 创新管理:从机制设计到文化养成-5.2 技术决策民主化-5.2.3草根创新的孵化土壤构建

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 草根创新的孵化土壤构建&#xff1a;IT团队技术决策民主化的底层实践1. 背景与挑战&#xff1a;传统技术决策体系的失效1.1 行业现状与痛点1.2 草根创新的价值潜力 2. 机制设…...

探秘Python 工匠:案例、技巧与工程实践:解锁Python进阶的通关秘籍

重要的放前面 Python 工匠&#xff1a;案例、技巧与工程实践 探秘Python 工匠&#xff1a;案例、技巧与工程实践&#xff1a;解锁Python进阶的通关秘籍 在Python的编程世界中&#xff0c;从入门小白到技术大牛的进阶之路往往充满挑战。Python工匠&#xff1a;案例、技巧与工…...

【langchain4j】Springboot如何接入大模型以及实战开发-AI问答助手(一)

langchain4j介绍 官网地址&#xff1a;https://docs.langchain4j.dev/get-started langchain4j可以说是java和spring的关系&#xff0c;spring让我们开发java应用非常简单&#xff0c;那么langchain4j对应的就是java开发ai的 “Spring” 他集成了AI应用的多种场景&#xff0c…...

解决Windows update服务启动拒绝访问的问题 | wuauserv 注册表拒绝访问的方法

在某些情况下,为了配置系统更新相关服务(例如禁用 Windows 自动更新),我们需要更改注册表中 wuauserv 项的权限。本教程将带你一步步操作,成功获取并修改权限。 修改注册表路径: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wuauserv 步骤一:打开注册表编辑…...

精益数据分析(5/126):解锁创业成功的关键密码

精益数据分析&#xff08;5/126&#xff09;&#xff1a;解锁创业成功的关键密码 大家好&#xff01;我一直坚信在技术与商业不断融合的当下&#xff0c;持续学习是保持进步的唯一途径。之前我们一起探讨了《精益数据分析》的部分内容&#xff0c;今天咱们接着深入学习&#x…...

Cribl 优化EC2 ip-host-region 数据

We’ve seen examples of using the magical powers of regex to customize Functions, extract fields, and filter events in real time. In this section, we’ll show you how to sprinkle your Lookups with regex magic. Lets walk through a Pipeline that demonstrates…...

【java实现+4种变体完整例子】排序算法中【桶排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格

以下是桶排序的详细解析&#xff0c;包含基础实现、常见变体的完整代码示例&#xff0c;以及各变体的对比表格&#xff1a; 一、桶排序基础实现 原理 将数据分到有限数量的桶中&#xff0c;每个桶内部使用其他排序算法&#xff08;如插入排序或快速排序&#xff09;&#xf…...

栈(c++)

今天介绍两种在c中写“栈”方法 1. #include <bits/stdc.h> using namespace std;class mystack { private:int a[1000];int curr -1; public:void push(int);void pop();int top();bool empyt();int size(); };int main() {mystack n;while(true){int a;cout<<&…...

GraphRAG与RAG的区别和原理简介

第一章 图谱与向量的共生逻辑 1.1 知识载体的局限性 向量空间模型虽能高效捕捉文本语义相似性&#xff0c;却无法解析知识的深层关联。例如&#xff0c;当用户询问“特斯拉4680电池与续航里程的关系”&#xff0c;向量检索可能仅返回技术参数片段&#xff0c;而无法解释化学成…...