基于RMI和C-S的服务发现

基于RMI和Socket的Java聊天软件 Java期末大作业,总算肝完了。这学期才开始接触Java,比起C语言java用起来不要太舒服。期末大作业就想着做一个能用的东西出来,于是就选了这个,经过小组成员的努力,最终还是把这玩意儿弄出来了。 服务器端: 采用RMI和Socket实现服务器端与客户端通信 关于RMI 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录服务器端:前言一、功能介绍及环境二、服务器端1.RMI2.Socket3.数据库4.基本逻辑三、客户端四、部署到服务器总结 前言 java大作业总算肝完了。这一路 阅读详情

一、介绍

主要用于有多个服务器的情况下,服务器启动后回向注册中心注册。当有客户端上线时,客户端通过服务编号,从注册中心得到此服务的所有服务器列表,然后选择性能最优的服务器连接。

二、服务发现需求分析

2.1服务发现的主要目的:
  1. 帮助客户端发现性能良好的服务器。
  2. 支持多个服务器在线。
  3. 客户都进行服务请求,并在多个在线服务器中进行选择。
  4. 客户端对服务器的选择可以实现:“负载均衡”。
  5. 服务发现支持服务器的“热插拔”。
2.2服务发现的核心是:注册中心
2.3注册中心的功能

1.服务器注册。
2.服务器下线。
3.向客户端提供服务列表。

2.4服务器的功能

1.向注册中心注册
2.下线。
3.响应客户端的服务性能检测。

2.5客户端的功能

1.向注册中心请求服务器列表。
2.定时刷新服务器列表。
3.和服务器建立连接,检测服务器性能(心跳检测)。
4.服务器选择。

三、详细过程描述

3.1图描述

在这里插入图片描述

3.2过程描述

1.当有服务器启动是时候,服务器通过自己编写的C-S框架和注册中心通信,并向注册中心注册。
2.注册中心把连接到的服务器放到Map里保存起来。
3.当有客户端请求服务连接时,客户端根据服务编号向注册中心发出请求。
4.注册中心返回该服务编号对应的所有服务器。
5.客户端接收到服务器列表后,把这个列表交给另一个线程负责维护。
6.这个线程负责定时连接注册中心,不断刷新服务器列表。
7.同时这个线程负责服务器性能的检测,判断最优服务器。
8.然后客户端和最优建立服务器连接。
9.如果连接失败,在和列表里的下一个服务器建立连接。
注:这里服务器和注册中心是长连接,其余连接都是短连接。

四、源代码

内有详细注释
[GitHub] https://github.com/AiunCode/ServiceDiscovery

我们为什么需要服务发现?服务发现的基本概念和流程,并通过实践案例说明如何利用服务发现构建微服务架构 Why Do We Need Service Discovery? 在现代分布式系统架构中,服务发现(Service Discovery)在微服务架构、云计算和容器化架构等方面扮演着至关重要的角色。服务发现旨在根据服务名、IP地址或其他标识符动态查找服务提供者的位置信息,包括网络地址、端口号、协议类型、QoS参数等。通常情况下,客户端应用需要通过服务发现模块获取服务提供者的可用性信息,并选择合适的服务实例进行访问,从而实现分布式系统中的软负载均衡和高可用。服务发现的目标是在分布式环境中自动发现和管理服务,提供服务路由和负载均衡等功能。 阅读详情

相关推荐

分布式程序java 实验名称 基于Java RMI的C/S编程实验

实验名称 基于Socket的C/S编程实验 实验名称 基于Java RMI的C/S编程实验

【Spring Cloud】为什么要使用服务发现?

为什么要使用服务发现? 传统的项目而言,服务器端的服务实例的网络地址是相对固定的。而基于云端、现代化的微服务服务实例的网络地址往往是动态更新的。由于服务器端的服务实例扩展、维护、升级,导致服务器端服务实例的IP地址、端口发生变化,从而使得客户端无法获取服务实例新的地址进行正常的调用。 服务发现为解决此类问题的一个解决方案,服务发现实时的获取服务器端服务实例的最新网络地址生成服务注册表,并提供给路由...

horse_well的博客 785

使用SAM进行遥感图像语义分割

SAM(Segment Anything Model)的成功表明了以数据为中心的机器学习的重要性。然而,由于遥感(RS)图像注释的困难和高成本,大量有价值的RS数据仍然没有被标记,特别是在像素级。在这项研究中,我们利用SAM和现有的RS物体检测数据集,开发了一个高效的管道来生成大规模的RS分割数据集,称为SAMRS。SAMRS在规模上超过了现有的高分辨率RS分割数据集几个数量级,并提供了物体类别、位置和实例信息,可用于语义分割、实例分割和物体检测,无论是单独还是组合。

lalula的博客 7453

【最小Demo】Java RMI入门 使用Registry、Naming、Zookeeper(注册中心)实现rmi

【最小Demo】Java RMI入门 使用Registry、Naming、Zookeeper(注册中心)实现rmi

alwarse 2644

全志DRM框架下LVDS双屏异显配置实战

本文详细介绍了在全志DRM框架下配置LVDS双屏异显的实战经验。涵盖硬件连接、内核配置、设备树修改、背光控制及U-Boot适配等关键步骤,重点解析屏参转换技巧与双屏route配置,帮助开发者解决工业控制台等多屏应用中的显示适配问题,提升开发效率。

rnn9storyteller的博客 814

YOLOv11改进 | 融合改进篇 | 利用尺度统一检测头DynamicHead融合P2增加小目标检测层(让小目标无所遁形)

本文给大家带来的最新改进机制是针对性的改进,针对于小目标检测增加P2层针对于大目标检测增加P6层利用DynamicHead(原版本一比一复现,全网独一份,不同于网上魔改版本)进行检测,其中我们增加P2层其拥有更高的分辨率,这使得模型能够更好地捕捉到小尺寸目标的细节。我们增加P6层是一个较低分辨率但具有更大感受野的特征层。对于大尺寸目标,这意味着模型可以更有效地捕捉到整体的结构信息。在这些的基础上我们配合DynamicHead可以使模型根据不同尺寸的目标动态调整其检测策略,进一步提升模型的精度。

Snu77的博客 3955

rmi|简单实例

Remote接口: 用于标识可以一个类或接口,被标识的类或接口的方法可以被非本地JVM调用。即运行在服务器JVM中被Remote标识类或接口的方法,可以被运行在客户端JVM中类调用。 1 创建被Remote标识的类,即被客户端远程调用的类 package com.demo.rmi; import java.io.Serializable; import java.rmi.Remote; /...

白衬衫猿 405

在 SAP 中,Primary Cost Element(初级成本要素)与Secondary Cost Element(次级成本要素)的核心区别、作用及业务含义可归纳如下

摘要:SAP中初级成本要素与次级成本要素的核心区别在于:初级要素必须关联FI模块的损益科目,直接影响财务报表,用于记录外部成本(如电费、薪酬);次级要素仅存在于CO模块,用于内部成本分配(如分摊、作业分配),不影响外部报表。初级要素是"外部成本入口",次级要素是"内部成本搬运工",二者共同实现成本的多维度追踪与管理。

金牌架构师 762

让C++也支持RMI

http://www.vckbase.com/document/viewdoc/?id=1846 作者:王树栋下载源代码摘要RMI( Remote Method Invocation),远程方法访问,作为java最早的分布式解决方案给网络程序的设计带来了极大的方便。尤其是在做C/S开发中,程序员不必关心底层网络通讯细节,即可像调用本地对象方法一样调用远端对象方法,方便了程序员编程。

杨德龙的专栏 3027

AIGC实战——基于Transformer实现音乐生成

Transformer 是最流行的音乐生成技术之一,因为音乐可以视为一个序列预测问题,Transformer 模型将音符视为一个个符号的序列(类似于句子中的单词),从而用于生成音乐。Transformer 模型基于先前音符预测下一个音符,生成音乐作品。在本节中,将学习如何处理音乐数据,并应用 Transformer 生成与给定训练集风格相似的音乐。

盼小辉丶的博客 1万+

SDA 还是 SDI:SAP HANA 数据虚拟化与数据集成的取舍、组合与实战

结论先放在前面:SDA 面向数据虚拟化与联邦查询,强调不落地、不复制、按需实时访问;SDI 面向数据集成与复制,强调抽取、转换、装载与近实时增量同步。两者共享 Remote Source 与 Adapter 的理念,但侧重点与运行时组件明显不同。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 586

KryoNet入门指南:10分钟构建你的第一个Java网络应用

KryoNet是一个基于Kryo的Java TCP/UDP客户端/服务器库,提供简洁高效的网络通信API。它通过NIO实现高性能数据传输,自动处理对象序列化,非常适合游戏开发、客户端/服务器应用和进程间通信。本文将带你快速掌握KryoNet的核心功能和使用方法,轻松构建你的第一个Java网络应用。 ## 🚀 什么是KryoNet? KryoNet是一个轻量级Java网络库,它将强大的Kryo

gitblog_00676的博客 381

Linux内核驱动模型--PCIe(PCI Express)驱动​​

本文系统介绍了Linux内核中PCIe驱动的设计与实现。首先从架构定位入手,指出PCIe驱动基于PCI子系统扩展支持高速、低功耗特性。核心数据结构struct pci_driver包含设备匹配表id_table、生命周期函数probe/remove等关键组件。文章详细解析了驱动与设备的绑定流程、资源管理机制,并重点阐述了MSI-X中断、电源管理、热插拔和多队列等高级特性实现方案。最后提供了lspci、dmesg等调试工具的使用方法,总结了PCIe驱动在支持高性能设备中的关键作用。全文通过架构设计、核心结构、

amy_mhd的博客 429

B/S,C/S架构混合使用

一般而言,我们平常接触的大多数项目都应该是单纯使用B/S或是C/S,除非在特殊场合,否则比较少混合使用B/S,C/S架构。首先说一下对这二种架构特点的一些个人理解。B/S应该是目前很多项目都应用的架构,浏览器的方式使得用户的使用十分方便,用户可以何时何地通过Internet访问URL而进行相应的工作,升级维护也能比较集中,缺点就是浏览器的表现能力受限以及常常受非议的安全性问题,如果软件的应用范围区...

iteye_8158的博客 2142

【第07例】IPD体系进阶: 6 个技术评审点(TR)

TR技术评审点

产品线负责人 4425

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

rmi远程调用被拒绝_深入理解RPC和RMI的区别

说明:本文为牛旦教育原创,转载请标注来源。原文: 深入理解RPC和RMI的区别https://mp.weixin.qq.com/s/mgMJW1y344UuTzJyCJX4NA1. RPC与RMI的核心区别首先,RPC(Remote Procedure Call,远程过程调用)和RMI(Remote Method Invocation,远程方法调用)是两种可以让用户从一台电脑调用不同电脑上面的方法...

weixin_39525007的博客 219

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

B/S,C/S架构混合使用 (转)

http://www.blogjava.net/nighty/archive/2008/05/06/198669.html 一般而言,我们平常接触的大多数项目都应该是单纯使用B/S或是C/S,除非在特殊场合,否则比较少混合使用B/S,C/S架构。首先说一下对这二种架构特点的一些个人理解。B/S应该是目前很多项目都应用的架构,浏览器的方式使得用户的使用十分方便,用户可以何时何地通过Internet...

backsnow 1432

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

关于RMI的某些认识

1、B/S结构中,从服务器端S是无法主动向客户端C进行“推”操作的,但是rmi可以,客户端lookup到一个服务器端的远程对象后,可以向服务器端注册一个存在于客户端上的远程对象,从而使得服务器端能够主动向客户端“推”信息,最典型的就是从服务器端诸个更新客户端界面的的某些状态,注意,这是服务器端发起的。我猜想JMS大概就是根据这个原理来做的。2、rmic有2个参数 -v1.1 和 -v1.2。   

安顿咖啡 andunkafei 1808

服务端网络通信RMI

服务端网络通信——RMI

weixin_43730892的博客 753

RMI底层实现详解

RMI底层实现详解什么是RPC?RPC调用流程什么是RMI ?创建服务端句柄创建客户端句柄接口约定RMI缺点总结 第一次写博客,工作这么多年了,总是从别人的博客寻找答案,打算从现在开始每周坚持写一次博客,一是加深对某个知识点的理解,二是为了时不时回来翻一翻,回忆那些平时不常用到的知识。 打算写RMI是因为有一次被问到如何自己实现一个RPC框架,当时就懵逼了,平时只知道使用,但是是怎么实现的还真不清...

wnnpnn的博客 973

java rmi 的局限_java rmi浅谈

标签:首先比较下RPC和RMI的差别:首先java提供了RMI的api,jdk1.5之后虚拟机自动生成两个类:存根类stub和骨架类skelton。 stub是给客户端的,当客户端调用远程对象的一个方法时,实际上是调用本地存根对象的相应方法。skelton负责在服务端为远程对象接受客户端的请求。RMI必须要有JVM支持,所以,如果C,S都使用java开发,可以考虑使用RMI。RPC可以跨语言,客户...

weixin_31813357的博客 371

java soap rmi_转 RMI、RPC、SOAP通信技术介绍及比对

http://www.open-open.com/home/space.php?uid=37924&do=blog&id=89741、RMI使用java的程序员,对于RMI(RemoteMethod Invoke,远程方法调用)一定不陌生,在java中,为了在分布式应用开发时,能够方便调用远程对象,java提供了RMI的API。在 RMI 中,远程对象按照好象它是本地行事,客户机应...

weixin_36424234的博客 171

(转)用c++实现java的rmi服务

  原文链接 http://www.vckbase.com/document/viewdoc/?id=1846 作者:王树栋   摘要 RMI( Remote Method Invocation),远程方法访问,作为java最早的分布式解决方案给网络程序的设计带来了极大的方便。尤其是在做C/S开发中,程序员不必关心底 层网络通讯细节,即可像调用本地对...

eric的学习笔记 338

java soap rmi_RMI、RPC、SOAP通讯技术介绍及比对 - XML/SOAP

RMI、RPC、SOAP通信技术介绍及比对1、RMI使用java的程序员,对于RMI(RemoteMethod Invoke,远程方法调用)一定不陌生,在java中,为了在分布式应用开发时,能够方便调用远程对象,java提供了RMI的API。在 RMI 中,远程对象按照好象它是本地行事,客户机应用程序会直接调用远程对象存根上的方法,因此,调用起来就如本地对象一样方便。RMI中封装了对象和请求的网络...

weixin_36241311的博客 209

java soap rmi_RMI、RPC、SOAP通信技术介绍及比对

1、RMI使用java的程序员,对于RMI(RemoteMethod Invoke,远程方法调用)一定不陌生,在java中,为了在分布式应用开发时,能够方便调用远程对象,java提供了RMI的API。在 RMI 中,远程对象按照好象它是本地行事,客户机应用程序会直接调用远程对象存根上的方法,因此,调用起来就如本地对象一样方便。RMI中封装了对象和请求的网 络传送,使得异地的对象服务直接可用。但RM...

weixin_39593519的博客 110
上一篇: 交叉列表
下一篇: 链表反转
CodAlun
博客等级 码龄8年 46粉丝 96原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值