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

网络编程-

文章目录

    • 网络编程套接字
    • UDP/TCP的api使用


网络编程套接字

socket,是操作系统给应用程序(传输层给应用层)提供的api,Java也对这个api进行了封装。

socket提供了两组不同的api,UDP有一套,TCP有一套,本文主要介绍api的使用.

这里介绍TCP和UDP的区别:
在这里插入图片描述
连接:通信双方各自保存对方的信息,就是连接.两个通信实体之间建立的一条可靠的、有序的、双向的通信通道。

可靠传输和不可靠传输:可靠传输是发送方可以知道消息有没有被接收方收到

面向字节流:网络中传输的数据的基本单位是字节

面向数据报:每次传输的基本单位是数据报

全双工:一个信道可以双向通信,就像公路一样是双向车道

UDP/TCP的api使用

Java把系统原生的api进行了封装,操作系统中有一类文件叫做scoket文件,它抽象的表示了"网卡"这样的设备,通过操作scoket文件就可以对网卡进行操作.

通过网卡发送数据,就是写scoket文件.
通过网卡接收数据,就是读socket文件.

UDP scoket api的使用

DatagramScoket是UDP scoket,用于接收和发送数据报.

核心的类有两个:
1.DatagramScoket

DatagramScoket是UDP scoket,用于接收和发送数据报.
DatagarmScoket的构造方法

方法说明
DatagramSocket()创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口(一般用于客户端)
DatagramSocket(int port)创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(port就是端口号)

DatagramScoket方法

方法名说明
void receive(DatagramPacket p)从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待)
void send(DatagramPacket p)从此套接字发送数据报包(不会阻塞等待,直接发送)
void close()关闭数据报套接字

在这里插入图片描述
这里的DatagramPacket p是作为输出型参数的

小知识:
输出型参数:输出型参数是一个变量,函数会修改它的值,并将修改后的值传递回调用者。调用者可以通过这个参数获取函数处理后的数据。就像是我们自己带饭盒去食堂吃饭,饭盒就相当于DatagramPacket,打饭的阿姨会帮我们把饭盒装满饭菜,此时打饭的阿姨就是void receive.

2.DatagramPacket

UDP面向数据报,每次发送接收数据的基本单位,就是一个UDP数据报.

构造方法:

方法说明
DatagramPacket(byte[] buf, int length)构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数组buf中,接收指定的长度(length)
DatagramPacket(byte[] buf,int offset,int length,SocketAddress address)构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数组buf中,接收指定的长度(length),address表示指定的目的主机的ip和端口号

常用方法:

方法说明
InetAddress getAddress()从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址
int getPort()从接收的数据报中,获取发送端主机的端口号,或者从发送的数据报中,获取接收端主机的端口号
byte[] getData()获取数据报中的数据

利用上述的方法及概念我们实现一个回显服务器程序;

package net;/*
服务器*/import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class UdpEchoServer {private DatagramSocket socket=null;//服务器一般都是要自己指定端口号public UdpEchoServer(int port) throws SocketException {socket=new DatagramSocket(port);}public void start() throws IOException {//服务器需要不停的处理请求,所以我们这里用while循环while (true){//1.等待客户端发送请求,并用DatagramPacket保存,如果没有请求,就进入阻塞.DatagramPacket requstPacket=new DatagramPacket(new byte[4399],4399);socket.receive(requstPacket);//2.将收到的请求构造成字符串,便于后边做出响应的处理String requst=new String(requstPacket.getData(),0,requstPacket.getLength());//3.通过接收的数据,服务器做出响应,process就是具体做出响应的逻辑//这里的回显服务器我们直接返回客户端的输入即可,没什么深层次的逻辑String response=process(requst);//4.将响应后的数据报构造出并且发送//requstPacket.getSocketAddress()就是和服务器通信的对端的ip和端口.//这里就是把请求中的源ip和源端口,作为响应的目的ip和目的端口DatagramPacket resonsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requstPacket.getSocketAddress());socket.send(resonsePacket);}}private String process(String requst) {return requst;}public static void main(String[] args) throws IOException {UdpEchoServer server=new UdpEchoServer(9090);server.start();}
}
/*
客户端
*/
package net;import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket=null;//目标服务器的IP和端口private String serverIP;private int serverPOrt;//客户端一般可以使用系统随机分配的端口号public UdpEchoClient(String serverIP,int serverPOrt) throws SocketException {this.serverIP=serverIP;this.serverPOrt=serverPOrt;socket=new DatagramSocket();}public void start() throws IOException {Scanner scanner=new Scanner(System.in);while (true){if (!scanner.hasNext()){break;}//将从控制台读取到的数据存入requstString requst=scanner.next();//1.将requst构成数据报,并发送给服务器DatagramPacket requstPacket=new DatagramPacket(requst.getBytes(),requst.getBytes().length, InetAddress.getByName(serverIP),serverPOrt);socket.send(requstPacket);//2.等待服务器返回响应,构造数据报进行接收,并进行输出DatagramPacket responsePacket=new DatagramPacket(new byte[4399],4399);socket.receive(responsePacket);String response=new String(responsePacket.getData(),0,responsePacket.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {//"127.0.0.1"通用,代表本机端口号UdpEchoClient client=new UdpEchoClient("127.0.0.1",9090);client.start();}
}

代码分析:

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

TCP socket api的使用
TCP是面向字节流的,传输的基本单位是字节.

连接建立:从客户端Socket的构造方法发送连接请求,服务器的SerevrSocket监听到请求后并且调用accept()方法,这样就建立了连接,然后accept()方法在服务器中会生成一个新的Socket对象用来进行通信.

api介绍:
ServerSocket

构造方法:

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

方法:

方法说明
Socket accept()开始监听指定端⼝(创建时绑定的端⼝),有客⼾端连接后,返回一个Socket对象,并且基于Socket建立与客户端的连接,没有就阻塞等待
void close()关闭套接字

Socket

构造方法:

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

方法:

方法说明
InetAddress getInetAddress()返回套接字锁连接的地址
InputStream getInputStream()返回此套接字的输⼊流
OutputStream getOutputStream()返回此套接字的输出流

ServerSocket只能在服务器中使用,而Socket既可以在服务器中使用也可以在客户端使用.

TCP是有连接的,就类似需要客户端拨打电话,服务器来接听.

接下来我们用回显服务器案例来介绍TCP的api的使用以及是如何通信的.

首先我们编写一下服务器程序.

 private ServerSocket requstSocket=null;public TcpEchoServer(int port) throws IOException {requstSocket=new ServerSocket(port);}

通过ServerSocket提供的构造方法,给服务器分配一个端口号(这里我们需要注意,服务器是必须要指定端口号的,而客户端系统自己分配端口号就可以)

服务器的ServerSocket是用来监听请求的,如果有客户端发送请求,那么ServerSocket就会感知到

服务器:

 public void start() throws IOException {/*当ServerSocket监听到有客户端发来请求后,会调用accept()方法一旦连接建立,accept()方法就会返回一个新的Socket对象,这个Socket就是专门用来与该客户端进行通信的*/Socket clientSocket=requstSocket.accept();//把处理请求和返回相应的逻辑这里我们放到这个方法中来实现processConntion(clientSocket);}

当ServerSocket监测到有客户端发来连接的请求,ServerSocket会调用accept()方法,accept()方法会返回一个新的Socket对象,这就算是建立了连接而这个新的对象就是用来与客户端通信

上述过程就像是客户端的Socket想要通过服务器的ServerSocket认识服务器中的Socket.于是客户端的Socket就请求服务器的ServerSocket帮忙牵个线,搭个桥.服务器的ServerSocket就把服务器的Socket的电话号码给了客户端,而客户端的构造方法就类似于给服务器拨通了电话,而当前只是在响铃,而accept()方法就类似接听,只有调用accept()的方法后才算真正建立连接

在这里插入图片描述

private void processConntion(Socket clientSocket) {try(InputStream inputStream=clientSocket.getInputStream();OutputStream outputStream=clientSocket.getOutputStream()){Scanner scanner=new Scanner(inputStream);while (true){if (!scanner.hasNext()){break;}String requst=scanner.next();String response=process(requst);PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();}} catch (IOException e) {throw new RuntimeException(e);}}private String process(String requst) {return requst;}
try(InputStream inputStream=clientSocket.getInputStream();OutputStream outputStream=clientSocket.getOutputStream())

InputStream inputStream=clientSocket.getInputStream();就是从网卡内读数据

OutputStream outputStream=clientSocket.getOutputStream()就是往网卡内写数据

TCP中操作socket文件,对其进行读写(InputStream,OutputStream),就是在操作网卡,操作系统把网卡抽象成了一个文件.就像看电视,我们只需要操作遥控器即可,而不需要直接去电视脸上操作

客户端

public TcpEchoClient(String serverIP,int serverPort) throws IOException {socket=new Socket(serverIP,serverPort);}

执行上述代码就会和对应的服务器进行tcp的连接建立流程(在系统内核中)
内核走完流程,服务器这边就会从accept()返回,于是就可以通信了.

public void start() throws IOException {try (InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){Scanner scannerConsle=new Scanner(System.in);Scanner scannernetWork=new Scanner(inputStream);while (true){if (!scannerConsle.hasNext()){break;}String requst=scannerConsle.next();PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(requst);printWriter.flush();String response=scannernetWork.next();System.out.println(response);}} catch (IOException e) {throw new RuntimeException(e);}finally {socket.close();}}
Scanner scannerConsle=new Scanner(System.in);Scanner scannernetWork=new Scanner(inputStream);

在客户端上,scannerConsle是在控制台中读取数据,也就是我们用户输入的时候读取数据,并且转变为String 发送给服务器(就是通过OutputStream写入操作网卡的文件).

而scannernetWork就是在服务器做出响应后,通过inputStream读取网卡上的数据 最终打印出结果.

PrintWriter

PrintWriter 是 Java 中的一个类,位于 java.io 包中,用于以文本形式写入输出数据。它继承了 Writer 抽象类,提供了多种方法来方便地写入字符和字符串到文件或其他输出流中.

printWriter.flush();

这个方法的作用是刷新缓冲区.因为IO都是比较低效的操作,一次一次读写,太麻烦.缓冲区就将先把数据放到内存缓冲区中,等攒够了数据一起发送,这样就变得高效了,而printWriter.flush();就是将缓存区刷新,将数据一点一点发送出去,不用等到满了一股脑发出去.

在客户端运行完毕之后我们要cloose()

  socket.close();

在这里插入图片描述

TCP服务器客户端执行流程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上述客户端代码还存在一个问题:
如果有多个客户端发送连接请求,我们就会发现第一个客户端连接上服务器之后,服务器会从accept这里返回,进入具体处理请求的processConntion方法,接下来在具体处理请求方法的内部scanner.hasNext()处阻塞,等待客户端发送请求,此时如果有客户端发送请求,hasNextt继续向下执行,构造String,计算响应.返回响应给客户端.执行完上述操作后继续循环,等待客户端发送请求.

上面这种情况,如果是很多个客户端一起执行,即使其他客户端在内核已经建立了连接,但是由于服务器一直在processConntion方法中为第一个发送请求的客户端服务,一直在processConntion方法循环处理请求,所以其他的客户端无法执行到accept()方法,只是在内核建立连接,没有调用accept方法就不能算真正意义上的连接.其他的客户端也就无法执行.

针对上述问题我们如何改进?
就要用到我们之前学到的多线程,一个线程处理连接,另一个线程处理请求返回响应的逻辑.
但是如果有很多客户端,每次发送请求的时候都要创建一个新的线程,处理完成后销毁,对于系统资源的开销是比较大的,所以我们这里使用线程池.

完整代码展示:

/*
服务器
*/
package net;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
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 socket=null;public TcpEchoServer(int port) throws IOException {socket=new ServerSocket(port);}public void start() throws IOException {ExecutorService pool= Executors.newCachedThreadPool();while (true){Socket cilentSocket =socket.accept();pool.submit(new Runnable() {@Overridepublic void run() {processConnetion(cilentSocket);}});}}private void processConnetion(Socket cilentSocket) {try (InputStream inputStream=cilentSocket.getInputStream();OutputStream outputStream=cilentSocket.getOutputStream()){Scanner scanner=new Scanner(inputStream);while (true){if (!scanner.hasNext()){break;}String requst=scanner.next();String response=process(requst);PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();}} catch (IOException e) {throw new RuntimeException(e);}}private String process(String requst) {return requst;}public static void main(String[] args) throws IOException {TcpEchoServer server=new TcpEchoServer(9090);server.start();}
}
/*
客户端
*/
package net;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;public TcpEchoClient(String serverIP,int serverPort) throws IOException {socket=new Socket(serverIP,serverPort);}public void start() throws IOException {try (InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){Scanner scannerCon=new Scanner(System.in);Scanner scannerNet=new Scanner(inputStream);while (true){if (!scannerCon.hasNext()){break;}String requst=scannerCon.next();PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(requst);printWriter.flush();String response=scannerNet.next();System.out.println(response);}} catch (IOException e) {throw new RuntimeException(e);}finally {socket.close();}}public static void main(String[] args) throws IOException {TcpEchoClient client=new TcpEchoClient("127.0.0.1",9090);client.start();}}

相关文章:

网络编程-

文章目录 网络编程套接字UDP/TCP的api使用 网络编程套接字 socket,是操作系统给应用程序(传输层给应用层)提供的api,Java也对这个api进行了封装。 socket提供了两组不同的api,UDP有一套,TCP有一套&#x…...

DeepSeek助力学术论文写作[特殊字符]

宝子们,还在为学术论文写作发愁吗?DeepSeek来帮你!只要用对提示词,它就能变成你写作路上的超级助手。今天就来给大家分享一些超好用的提示词,助力学术论文写作,让你的论文在ChatGPT的辅助下闪闪发光✨。 一…...

从零创建DeepSeek:技术路径与实践探索

import tensorflow as tf摘要:本文详细阐述了从零开始创建DeepSeek的全过程,涵盖从项目启动的构思,到技术选型的考量,再到模型训练的精细操作,以及系统集成、测试优化和部署上线的各个环节。通过对这些步骤的深入解析&…...

MySQL技术公开课:Mysql-Server-8.4.4 Innodb 集群搭建与维护

MySQL技术公开课 - Mysql-Server-8.4.4 Innodb 集群搭建与维护 讲课内容: 1、Innodb集群框架介绍 2、Innodb集群部署(mysql-Server、mysql-shell、mysql-router安装配置) 3、Innodb集群维护(主备切换、启动与关闭、故障排除) Mysql-server商业版目前最新的是8.…...

VS Code User和System版区别【推荐使用System版本】and VSCode+Keil协同开发之Keil Assistant

VS Code User和System版区别 Chapter1 VS Code User和System版区别1. 对于安装而言2. 结束语 Chapter2 VS Code 安装、配置教程及插件推荐插件: Chapter3 VSCodeKeil协同开发之Keil Assistant1. 效果展示2. Keil Assistant简介3. Keil Assistant功能特性4. 部署步骤…...

动态规划两个数组dp问题系列一>最长重复子数组

目录 状态表示:状态转移方程:初始化:填表顺序:返回值:代码呈现: 状态表示: 状态转移方程: 初始化: 填表顺序: 返回值: 这里是以某一个位置为结尾定…...

在SpringBoot中使用UniHttp简化天地图路径规划调用实践

目录 写在最前面 前言 一、天地图路径规划简介 1、天地图相关服务 2、天地图路径规划接口 二、UniHttp简介 1、UniHttp是什么? 2、UniHttp能做什么? 三、UniHttp调用天地图接口 1、请求接口的定义 2、实际调用 3、相应结果展示 四、总结 写在…...

springboot与Freemarker

1 基本使用 1.1 介绍 FreeMarker 是一款模板引擎: 即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 是一个Java类库。 FreeMarker 被设计用来生成 HTML Web 页面…...

CMake无法生成可执行文件,一直生成库文件

CMakeLists的内容如下,一直生成的main是库文件,而不是可执行文件。本人是在进行鸿蒙的交叉编译的时候遇到,归结为cmake属性的差异。原内容如下: # 设置最低CMake版本要求 cmake_minimum_required (VERSION 2.8.0)# 设置项目名称 …...

PrimeFaces实战:IdleMonitor与Ajax的完美结合

在现代的Web开发中,用户交互的实时反馈是一个重要的用户体验环节。PrimeFaces作为一个强大的Java EE UI库,提供了许多便捷的功能组件,其中之一就是IdleMonitor。通过IdleMonitor,我们可以轻松地检测用户何时处于空闲状态以及何时从…...

搭建一个经典的LeNet5神经网络

第一章:计算机视觉中图像的基础认知 第二章:计算机视觉:卷积神经网络(CNN)基本概念(一) 第三章:计算机视觉:卷积神经网络(CNN)基本概念(二) 第四章:搭建一个经典的LeNet5神经网络 一、LeNet-5背景 LeNet-…...

Transformer多头注意力并行计算原理与工业级实现:从数学推导到PyTorch工程优化

一、核心数学原理剖析 1.1 多头注意力矩阵分解 Q XW^Q ∈ R^{nd_k} K XW^K ∈ R^{nd_k} V XW^V ∈ R^{nd_v} 多头分解公式: head_i Attention(QW_i^Q, KW_i^K, VW_i^V) 其中 W_i^Q ∈ R^{d_kd_k/h}, W_i^K ∈ R^{d_kd_k/h}, W_i^V ∈ R^{d_vd_v/h} (h为头数…...

OpenAI 的变化对行业意味着什么?

哎呀,中国AI的发展可是搅动了一番风云。害怕自己正在失去对 AI 话语权的掌控,OpenAI 决定是时候全力出击了。 除了最近意外发布的 o3-mini 模型之外,Sam Altman 昨天还宣布了接下来几周/几个月的路线图,而这些变化相当显著&#…...

LinkedList

一.IDEA的链表库 IDEA上实现链表的包,实现的是无头双向不循环链表:(并且这个链表有头尾节点) 二.自己实现一个无头双向不循环链表 1.创建链表的类,在链表内中定义一个节点的内部类,并且在链表的类中定义头…...

半遮挡检测算法 Detecting Binocular Half-Occlusions

【1. 背景】: 本文分析【Detecting Binocular Half-Occlusions:Empirical Comparisons of Five Approaches】Geoffrey Egnal和Richard P. Wildes于2002年发表在IEEE Transactions on Pattern Analysis and Machine Intelligence上,这是1篇中…...

零基础购买阿里云服务器,XShell连接云服务器

目录 1.环境搭建方式 2. 使用云服务器 3.使用终端软件登录到Linux 4.使用XShell登录主机 5.连接失败的原因: 下一篇更新:Linux的基础指令以及如何Linux的环境搭建 1.环境搭建方式 主要有四种: 1.直接安装在物理机上,虽然Linux有图形化…...

Mac ARM 架构的命令行(终端)中,删除整行的快捷键是:Ctrl + U

在 Mac ARM 架构的命令行(终端)中,删除整行的快捷键是: Ctrl U这个快捷键会删除光标所在位置到行首之间的所有内容。如果你想删除光标后面的所有内容,可以使用: Ctrl K这两个快捷键可以帮助你快速清除当…...

ESP学习-1(MicroPython VSCode开发环境搭建)

下载ESP8266固件:https://micropython.org/download/ESP8266_GENERIC/win电脑:pip install esptools python.exe -m pip install --upgrade pip esptooo.py --port COM5 erase_flash //清除之前的固件 esptool --port COM5 --baud 115200 write_fla…...

微信小程序性能优化

微信小程序的性能优化是提升用户体验的关键。以下是一些常见的优化策略和技巧: 1. 减少 setData 的调用频率和数据量 setData 是小程序中更新视图的主要方式,但频繁调用或数据量过大会导致性能问题。 减少调用频率:避免在短时间内多次调用…...

五十天精通硬件设计第31天-阻抗

系列文章传送门 50天精通硬件设计第一天-总体规划-CSDN博客 目录 1. 核心概念:特性阻抗 2. 阻抗不匹配的后果 3. 关键影响因素 4. 阻抗匹配方法 5. 设计实践要点 6. 工具与测试 7. 常见问题解决 总结 信号完整性中的阻抗问题主要涉及传输线的特性阻抗匹配,是确保高…...

docker部署dify结合deepseek构建知识库

序 本文主要研究一下本地docker部署dify结合deepseek构建知识库 步骤 dify git clone https://github.com/langgenius/dify.git git co tags/0.15.3 -b 0.15.3 cd docker cp .env.example .env docker-comopse up启动之后访问localhost docker-comopse.yaml # # WARNING…...

11.C语言 malloc() calloc() realloc()分配内存

目录 malloc 好处 坏处 总结 calloc 参数说明 作用 与 malloc 的区别 示例 优点 缺点 总结 realloc 参数说明 作用 示例 优点 缺点 注意事项 总结 总结区别 对比表格 malloc 函数功能:分配内存给 void* malloc(size_t size); 来看一下deep…...

可信大模型:LLM + 神经符号推理,解决复杂推理任务

可信大模型:LLM 神经符号推理,解决复杂推理任务 论文大纲一、Why:研究要解决的现实问题二、What:核心发现或论点三、How:研究的整体方法与关键细节3.1 前人研究的局限性3.2 创新方法/视角3.3 关键数据或实验支持3.4 可…...

基于大数据的全国热门旅游景点数据分析系统的设计与实现

【大数据】基于大数据的全国热门旅游景点数据分析系统的设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统主要包括登录注册、系统首页、图表分析、数据管理和个人信息五大功能模…...

Moya 网络框架

Moya 网络框架 定义enum类型,有多种接口就定义多少种,然后实现TargetType协议 import Foundation //导入网络框架 import Moyaenum DefaultService {//广告列表case ads(position : Int)case sheets(size:Int)case sheetDetail(data: String)case regi…...

【环境安装】重装Docker-26.0.2版本

【机器背景说明】Linux-Centos7;已有低版本的Docker 【目标环境说明】 卸载已有Docker,用docker-26.0.2.tgz安装包安装 1.Docker包下载 下载地址:Index of linux/static/stable/x86_64/ 2.卸载已有的Docker 卸载之前首先停掉服务 sudo…...

std::ranges::set_intersection set_union set_difference set_symmetric_difference

std::ranges::set_intersection:是 C20 引入的一个算法,用于计算两个已排序范围的交集。它将两个范围的交集元素复制到输出范围中。 std::ranges::set_intersection 用于计算两个已排序范围的交集。它将两个范围的交集元素复制到输出范围中。 注意事项…...

消息中间件深度剖析:以 RabbitMQ 和 Kafka 为核心

在现代分布式系统和微服务架构的构建中,消息中间件作为一个不可或缺的组件,承担着系统间解耦、异步处理、流量削峰、数据传输等重要职能。尤其是在面临大规模并发、高可用性和可扩展性需求时,如何选择合适的消息中间件成为了开发者和架构师们…...

笔试题笔记#6 模拟三道题和总结知识

两小时快乐模拟,最终三百分耻辱下播,(刷的题三道一组,时长两小时,第一题100分,第二题200分,第三题300分),第三题完全想错了,其实挺简单的,就是好久…...

生成对抗网络(GAN)的“对抗“过程解析:从图像合成到药物发现的跨领域应用

技术原理(数学公式示意图) 核心对抗公式 min ⁡ G max ⁡ D V ( D , G ) E x ∼ p d a t a [ log ⁡ D ( x ) ] E z ∼ p z [ log ⁡ ( 1 − D ( G ( z ) ) ) ] \min_G \max_D V(D,G) \mathbb{E}_{x\sim p_{data}}[\log D(x)] \mathbb{E}_{z\sim p_…...

[鸿蒙笔记-基础篇_自定义构建函数及自定义公共样式]

在开发中遇到比较复杂的界面的时候都会用到自定义组件,但是在自定义组件内部也会有一些公共的布局及公共的样式,这时就需要用到自定义构建函数和自定义构建样式。说白了就是:在ets文件中进行构建函数和构建样式的抽取封装。比较常用记录一下。…...

【C】初阶数据结构4 -- 双向循环链表

之前学习的单链表相比于顺序表来说,就是其头插和头删的时间复杂度很低,仅为O(1) 且无需扩容;但是对于尾插和尾删来说,由于其需要从首节点开始遍历找到尾节点,所以其复杂度为O(n)。那么有没有一种结构是能使得头插和头删…...

【动态路由】系统Web URL资源整合系列(后端技术实现)【nodejs实现】

需求说明 软件功能需求:反向代理功能(描述:apollo、eureka控、apisix、sentinel、普米、kibana、timetask、grafana、hbase、skywalking-ui、pinpoint、cmak界面、kafka-map、nacos、gateway、elasticsearch、 oa-portal 业务应用等多个web资…...

解读 Flink Source 接口重构后的 KafkaSource

前言 Apache Kafka 和 Apache Flink 的结合,为构建实时流处理应用提供了一套强大的解决方案[1]。Kafka 作为高吞吐量、低延迟的分布式消息队列,负责数据的采集、缓冲和分发;而 Flink 则是功能强大的流处理引擎,负责对数据进行实时…...

一场始于 Selector Error 的拯救行动:企查查数据采集故障排查记

时间轴呈现事故进程 17:00:开发人员小李正在尝试利用 Python 爬虫从企查查(https://www.qcc.com)抓取公司工商信息。原本一切正常,但突然发现信息采集失败,程序抛出大量选择器错误。17:15:小李发现&#x…...

代码随想录刷题攻略---动态规划---子序列问题1---子序列

子序列(不连续)和子序列(连续)的问题 例题1: 最长递增子序列 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列,删除(或不删除)数组中的…...

QEMU 搭建arm linux开发环境

Qemu 作为一款强大的开源虚拟化软件,为我们提供了一个便捷且经济实惠的方式来模拟各种硬件环境,从而在上面安装和学习 Linux 系统。本文将详细介绍如何使用 Qemu 搭建 Linux 学习环境, 环境准备 操作系统:建议使用 Ubuntu 20.04…...

PyQt组态软件 拖拽设计界面测试

PyQt组态软件测试 最近在研究PyQt,尝试写个拖拽设计界面的组态软件,目前实现的功能如下: 支持拖入控件,鼠标拖动控件位置 拖动控件边缘修改控件大小支持属性编辑器,修改当前选中控件的属性 拖动框选控件,点选控件 控…...

JAVA泛型介绍与举例

Java中,泛型用于编译阶段限制集合中元素的类型,或者限制类中某个属性的类型,编译过程中发生类型擦除,最终还是Object类型。 1. 集合中的泛型 集合默认可以存储任何类型的元素,即Object类型,当使用一个集合…...

JavaScript 内置对象-Math对象

在JavaScript中,Math 对象提供了一系列与数学相关的静态方法和属性,帮助开发者执行复杂的计算任务。无论是简单的算术运算还是高级的几何、统计计算,Math 对象都能提供强大的支持。本文将详细介绍 Math 对象的主要功能及其使用方法。 一、简…...

Ubuntu 22.04 Desktop企业级基础配置操作指南

一、网络配置 cd /etc/netplan vi 00-installer-config.yaml 设置如下所示: network:version: 2ethernets:eth0: # 替换为你的实际网络接口名称,如 ens33, enp0s3 等dhcp4: noaddresses:- 192.168.1.100/24 # 静态IP地址和子网掩码gateway4: 192.16…...

UE_C++ —— UObject Instance Creation

目录 一,UObject Instance Creation NewObject NewNamedObject ConstructObject Object Flags 二,Unreal Object Handling Automatic Property Initialization Automatic Updating of References Serialization Updating of Property Values …...

WPF的MVVMLight框架

在NuGet中引入该库&#xff1a; MVVMLight框架中的命令模式的使用&#xff1a; <StackPanel><TextBox Text"{Binding Name}"/><TextBox Text"{Binding Title}"/><Button Content"点我" Command"{Binding ShowCommand…...

【云安全】云原生- K8S kubeconfig 文件泄露

什么是 kubeconfig 文件&#xff1f; kubeconfig 文件是 Kubernetes 的配置文件&#xff0c;用于存储集群的访问凭证、API Server 的地址和认证信息&#xff0c;允许用户和 kubectl 等工具与 Kubernetes 集群进行交互。它通常包含多个集群的配置&#xff0c;支持通过上下文&am…...

binance python

binance-futures-connector 4.1.0 from binance.um_futures import UMFutures # U本位 USDT-M Futures /fapi/* # 币本位 COIN-M Delivery /dapi/* proxies { https: http://localhost:7890 } client UMFutures(proxiesproxies)apiKey"" apiSecret"" cl…...

LLaMA-Factory DeepSeek-R1 模型 微调基础教程

LLaMA-Factory 模型 微调基础教程 LLaMA-FactoryLLaMA-Factory 下载 AnacondaAnaconda 环境创建软硬件依赖 详情LLaMA-Factory 依赖安装CUDA 安装量化 BitsAndBytes 安装可视化微调启动 数据集准备所需工具下载使用教程所需数据合并数据集预处理 DeepSeek-R1 可视化微调数据集处…...

利用亚马逊云科技RDS for SQL Server配置向量数据存储

生成式人工智能&#xff08;AI&#xff09;正迎来又一个快速发展期&#xff0c;引起了开发者们的广泛关注。将生成式能力集成到商业服务和解决方案中变得非常重要。当前的生成式AI解决方案是机器学习和深度学习模型逐步进化迭代的结果。从深度学习到生成式AI的质变飞跃主要是由…...

ASP.NET Core SixLabors.ImageSharp v1.0 的图像实用程序类 web示例

这个小型实用程序库需要将 NuGet SixLabors.ImageSharp包&#xff08;版本 1.0.4&#xff09;添加到.NET Core 3.1/ .NET 6 / .NET 8项目中。它与Windows、Linux和 MacOS兼容。 这已针对 ImageSharp v3.0.1 进行了重新设计。 它可以根据百万像素数或长度乘以宽度来调整图像大…...

JVM 底层探秘:对象创建的详细流程、内存分配机制解析以及线程安全保障策略

文章目录 1. 类加载检查2. 内存分配① 指针碰撞② 空闲列表线程安全问题&#xff1a; 3. 内存空间初始化4. 对象头设置5. 对象初始化 当Java虚拟机遇到一条 new指令时&#xff0c;会执行以下步骤来创建对象&#xff1a; 1. 类加载检查 首先检查new指令的参数是否能在常量池中…...

SpringCloud框架下的注册中心比较:Eureka与Consul的实战解析

摘要 在探讨SpringCloud框架中的两种注册中心之前&#xff0c;有必要回顾单体架构与分布式架构的特点。单体架构将所有业务功能集成在一个项目中&#xff0c;优点是架构简单、部署成本低&#xff0c;但耦合度高。分布式架构则根据业务功能对系统进行拆分&#xff0c;每个模块作…...