Delphi实例分析:远程传输数据和文件

Delphi实现WebService带身份认证的数据传输 在WebService中,用户身份认证信息可以在客户端通过soap头(soapheader)进行传送。在WebService服务端的编写中,需要对soap头进行处理,这个处理过程就是提取SoapHeader中的用户认证信息进行验证。下面就来看看在Delphi中这个身份认证是如何实 阅读详情
[摘要] 在Windows操作系统的平台上,WinSock是首选的网络编程接口,用于在网络上传输数据和交换信息,它构成了Windows操作系统进行网络编程的基础。对于编写网络应用程序来说,WinSock是一门非常重要的并且必须掌握的知识,虽然现在有很多的工具如FTP程序可以在网络上传输数据和文件,但是通过WinSock编程具有更大的灵活性,因为它不需要关心网络连接的细节问题。
[关键字] Delphi Windows 远程传输
【eNet硅谷动力专稿】在Windows操作系统的平台上,WinSock是首选的网络编程接口,用于在网络上传输数据和交换信息,它构成了Windows操作系统进行网络编程的基础。对于编写网络应用程序来说,WinSock是一门非常重要的并且必须掌握的知识,虽然现在有很多的工具如FTP程序可以在网络上传输数据和文件,但是通过WinSock编程具有更大的灵活性,因为它不需要关心网络连接的细节问题。然而用WinSock编程却相当复杂,但是在Delphi中我们并不需要直接与WinSock的API函数打交道,因在Delphi中的TClientSocket组件和TServerSocket组件封装了WinSock的大部分API函数,使得对WinSock的编程大大简化。在网络通信协议的面向连接服务中,进行传输数据和交换信息之前,通信双方应该建立一条用于进行数据交换的“链路”,通信双方就是利用这个“链路”进行稳定可靠的数据传输,由于建立通信的双方都处于收发信息的状态,并且保证了数据传输的稳定性,所以在传输较大的文件时,具有较高的效率。而建立“链路”和断掉“链路”都需要消耗一定的时间,所以在传输较小文件时的效率是比较低的。

  在这里我们将了解winsock如何实现远程传输数据和文件。在一个局域网内不同的计算机上分别运行服务器端程序和客户端程序。服务器端运行后就启动,socket将建立侦听状态。客户端运行后,在客户端程序中填写服务器IP地址,然后单击“连接”按钮,向服务器端发出一个建立连接的请求,如图1所示。如果通客户端程序过端口成功和服务器端连接,服务器端的状态栏就会有“已和客户端连接”的提示,并准备传输文件,如图2所示。

  
delphi

  图1


  
delphi

  图2


  单击“发送”按钮,在弹出的对话框中选择一个准备发送的文件,然后客户端将文件的大小和其他信息等发送到服务器端,服务器端接受到文件的信息后通知客户端开始传送文件,文件的数据需要多次传递,服务器将文件全部接受并保存。系统运行如图3、图4所示:

  
delphi

  图3


  
delphi

  图4


  服务器端程序编写:

新建一个项目,并把一个TServerSocket组件放到Form1窗体上,Active设为True;端口Port设为2000,其它属性按默认值。服务器端程序代码如下:

  unit Unit1;

  interface

  uses

   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

   Dialogs, StdCtrls, ScktComp, ComCtrls, DB, DBTables, XPMan;

  Const

   MP_QUERY ='1';

   MP_REFUSE ='2';

   MP_ACCEPT ='3';

   MP_NEXTWILLBEDATA ='4';

   MP_DATA ='5';

   MP_ABORT ='6';

   MP_OVER ='7';

   MP_CHAT ='8';

   MP_END ='9';

   MP_FILEPROPERTY ='0';

   iBYTEPERSEND=1024;

  type

   TForm1 = class(TForm)

  Serversocket: TServerSocket;

   Query1: TQuery;

   GroupBox1: TGroupBox;

   Memo1: TMemo;

   XPManifest1: TXPManifest;

   StatusBar1: TStatusBar;

   Button1: TButton;

   procedure serversocketClientConnect(Sender: TObject; Socket: TCustomWinSocket);

   procedure serversocketClientRead(Sender: TObject; Socket: TCustomWinSocket);

   procedure serversocketClientError(Sender: TObject; Socket: TCustomWinSocket;

   ErrorEvent: TErrorEvent; var ErrorCode: Integer);

   procedure Button1Click(Sender: TObject);

   procedure FormCreate(Sender: TObject);

  

   private

   fsRecv:TMemoryStream;

   public

   { Public declarations }

   end;

  

  var

   Form1: TForm1;

   bReadText:boolean;

  

  implementation

  

  {$R *.dfm}

  

  procedure TForm1.FormCreate(Sender: TObject);

  begin

   Serversocket.Port:=2000;//设置侦听端口为2000;

   bReadText:= true;

   Serversocket.Open;

   StatusBar1.SimpleText:=' 就绪 ';

  end;

  

  procedure TForm1.ServersocketClientConnect(Sender: TObject;

   Socket: TCustomWinSocket);

  begin

   Statusbar1.SimpleText:=' 已和IP地址为 '+Socket.RemoteAddress+' 客户端连接 ';

  end;

  

  procedure TForm1.serversocketClientRead(Sender: TObject; Socket: TCustomWinSocket);

  var

   sTemp ,existfile, newfile : string;

   bufRecv:Pointer;

   iNum:integer;

   begin

   Memo1.Lines.Add('received size :' + intToStr(Socket.ReceiveLength));

   if bReadText then

   begin

   sTemp:=Socket.ReceiveText;

   case sTemp[1] of

   MP_QUERY:

   begin

   Memo1.Lines.Add('receive MP_QUERY');

   existfile:=Copy(sTemp,2,Length(STemp)); ;

   newfile:= 'c:\Administrator\'+ExtractFileName(existfile);

   copyfile(pchar(existfile),pchar(newfile),false);

   serversocket.Socket.Connections[0].SendText(MP_ACCEPT);

  

   fsRecv := TMemoryStream.Create;

  

   serversocket.Socket.Connections[0].SendText(MP_REFUSE+'');

   end;

   MP_FILEPROPERTY:

   begin

   Memo1.Lines.Add('receive MP_FILEPROPERTY');

   serversocket.Socket.Connections[0].SendText(MP_NEXTWILLBEDATA);

   end;

   MP_NEXTWILLBEDATA:

   begin

   Memo1.Lines.Add('receive MP_NEXTWILLBEDATA');

   bReadText:=false;

   serversocket.Socket.Connections[0].SendText(MP_DATA);

   end;

   MP_END:

   begin

   Memo1.Lines.Add('receive MP_END');

   fsRecv.Free;

   bReadText:=true;

   end;

   MP_ABORT:

   begin

   Memo1.Lines.Add('receive MP_ABORT');

   fsRecv.Free;

   bReadText:=true;

   end;

   MP_CHAT:

   begin

   Memo1.Lines.Add('receive MP_CHAT');

   end;

   end;{of case}

   end

   else

   begin

   try

  

   GetMem(bufRecv, iBYTEPERSEND);

   iNum := Socket.ReceiveBuf(bufRecv^, iBYTEPERSEND);

   fsRecv.WriteBuffer(bufRecv^, iNum);

   finally

   FreeMem(bufRecv);

   end;{of try}

   bReadText:=true;

  

   if iNum = iBYTEPERSEND THEN

   begin

   serversocket.Socket.Connections[0].SendText(MP_NEXTWILLBEDATA);

   end

   else

   begin

  

   fsRecv.Free;

   serversocket.Socket.Connections[0].SendText(MP_END);

   end;

   end;

   end;

  procedure TForm1.serversocketClientError(Sender: TObject; Socket: TCustomWinSocket;

   ErrorEvent: TErrorEvent; var ErrorCode: Integer);

  begin

   Memo1.Lines.Add('ErrorCode :' + IntToStr(ErrorCode));

   ErrorCode := 0;

  end;

  

  procedure TForm1.Button1Click(Sender: TObject);

  var

   i, j: integer;

  begin

   J := serversocket.Socket.ActiveConnections;

   Memo1.Lines.Add('ActiveConnectiong is ' + inttostr(j));

  end;

  end.

  客户端程序编写:

  新建一个工程,并把一个TClientSocket组件放到Form1窗体上,Port设为2000(端口号可任意设置,要求客户端和服务器端统一),其它属性按默认值。具体客户端程序代码如下:

  unit Unit2;

  interface

  uses

   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

   Dialogs, StdCtrls, ScktComp, ComCtrls, XPMan;

  const

   MP_QUERY ='1';

   MP_REFUSE ='2';

   MP_ACCEPT ='3';

   MP_NEXTWILLBEDATA='4';

   MP_DATA ='5';

   MP_ABORT ='6';

   MP_OVER ='7';

   MP_CHAT ='8';

   MP_END ='9';

   MP_FILEPROPERTY ='0';

   iBYTEPERSEND=1024;

  

  type

   TForm1 = class(TForm)

   cs: TClientSocket;

   OpenDialog1: TOpenDialog;

   StatusBar1: TStatusBar;

   GroupBox1: TGroupBox;

   edtIPAddress: TEdit;

   Edit2: TEdit;

   btnSendFile: TButton;

   btnConnect: TButton;

   XPManifest1: TXPManifest;

   GroupBox2: TGroupBox;

   Label1: TLabel;

   edtSize: TEdit;

   Memo1: TMemo;

   procedure btnConnectClick(Sender: TObject);

   procedure btnSendFileClick(Sender: TObject);

   procedure FormCreate(Sender: TObject);

   procedure csRead(Sender: TObject; Socket: TCustomWinSocket);

   private

   fsSend:TFileStream;

   public

   { Public declarations }

   end;

  

  var

   Form1: TForm1;

  

  implementation

  

  {$R *.dfm}

  procedure TForm1.btnConnectClick(Sender: TObject);

   begin

   cs.Address := edtIPAddress.Text;

   cs.Port:=2000;

   cs.Open;

   end;

  

  procedure TForm1.btnSendFileClick(Sender: TObject);

  begin

  if OpenDialog1.Execute then

   Begin

   cs.Socket.SendText(MP_QUERY+OpenDialog1.FileName);

   end;

  end;

  

  procedure TForm1.FormCreate(Sender: TObject);

  begin

   edtipaddress.Text:='127.0.0.1';

  end;

  

  procedure TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket);

  var

   sRecv:string;

   iNum:integer;

   bufSend:pointer;

   begin

   sRecv:=Socket.ReceiveText;

   Memo1.Lines.Add('sRecv =' + sRecv);

   Case sRecv[1] of

   MP_REFUSE:ShowMessage('Faint,be refused!');

   MP_ACCEPT:begin

   Memo1.Lines.Add('MP_ACCEPT');

   fsSend:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);

   edtSize.Text:=IntToStr(fsSend.Size);

   edit2.text:='total count:'+IntToStr(Trunc(fsSend.Size/iBYTEPERSEND)+1);

   cs.Socket.SendText(MP_FILEPROPERTY+IntToStr(Trunc(fsSend.Size/iBYTEPERSEND)+1));

   fsSend.Seek(0, soFromBeginning);

   end;

   MP_NEXTWILLBEDATA:begin

   Memo1.Lines.Add('MP_NEXTWILLBEDATA');

   Socket.SendText(MP_NEXTWILLBEDATA);

   end;

   MP_DATA:

   begin

   Memo1.Lines.Add('MP_DATA');

   try

   GetMem(bufSend, iBYTEPERSEND);

   iNum := fsSend.Read(bufSend^, iBYTEPERSEND);

   cs.Socket.SendBuf(bufSend^, iNum);

   Memo1.Lines.Add('Send Buf finished');

   finally

   FreeMem(bufSend);

   end;{of try}

   end;

   MP_END:

   begin

   Memo1.Lines.Add('MP_END');

   fsSend.Free;

   end;

   MP_ABORT:begin

   Memo1.Lines.Add('MP_ABORT');

   fsSend.Free;

   end;

   end;

   end;

  end.
DELPHI服务端开发实践教程与资源集 DELPHI是Borland公司开发的一款强大的快速应用程序开发(RAD)工具,它以高效、稳定和可快速部署而著称。在服务端开发方面,DELPHI同样展示出它得天独厚的优势,包括支持高效的多线程处理、易于使用的数据库连接以及丰富的网络组件等。入门DELPHI服务端开发的第一步是安装与配置开发环境。安装DELPHI后,你会得到一个集成开发环境(IDE),它包括代码编辑器、调试器、可视化设计器等工具。接下来,你可以通过创建一个新的服务端项目来开始你的DELPHI服务端之旅。 阅读详情

相关推荐

Delphi JSON处理工具包

JSON(JavaScript Object Notation)已经成为数据交换的常用格式,尤其是在Web应用中。Delphi作为一款功能强大的开发工具,通过JSON控件提供了对JSON数据格式的全面支持。这些控件不仅能够解析和生成JSON数据,还提供了数据绑定和数据导航的功能。对于Delphi开发者来说,这意味着可以更加便捷地处理JSON数据,实现快速开发。在这一章中,我们将对Delphi JSON控件的主要功能进行介绍,并探讨它们是如何简化JSON数据处理过程的。

weixin_28787801的博客 1161

delphi webserver soap头(soap header)信息传送

在做一个webserver 接口的时候,需要在soap header传送登录后的SessionId,通常delphi生成接口后传送的XML里是不会有包括header数据信息的,这就只能是写代码增加上去。 那么,首先我们需要先自行定义一个类: const IS_TEXT = $0020; {一个常量,也很重要} //这个定义了 Header信息基础类 TSessionIdHeader = class(TSOAPHeader) private FValue: string;

tanqth的专栏 1万+

Delphi SPComm串口通信实例教程

Delphi是一种集成开发环境(IDE),支持面向对象的编程语言Object Pascal。它最初由Borland公司开发,现在由Embarcadero Technologies维护。Delphi允许开发者快速设计应用程序的用户界面,并通过数据访问、报表生成、串口通信等多种组件来扩展应用功能。串口通信,全称为串行通信,是一种在电子设备之间进行数据交换的方式。与并行通信相比较,串行通信通过单一的通信线路上逐位顺序传输数据,这使得串口通信在长距离传输和布线方面具有优势。

weixin_35294091的博客 1014

局域网内传文件或文件内容

      前一段时间由于工作需要写了一个局域网内传文件的小程序。后来在优快云上也看到了有朋友在发这样的帖子。于是整理了一下,发表出来。希望能对需要的朋友有所帮助。我也是初学。也可能在高手们看来这样的程序太菜了。呵呵。由于这个程序本来就很简单,我只是作了封装而已。在此的目的只是想把代码发表出来。所以不会对基本的概念性的知识再作解释。     在这个程序当中我用了四个控件。TIdTCPServer

jinzhili的专栏 3670

Delphi实现SAP RFC接口编程实战

本文还有配套的精品资源,点击获取 简介:本资源提供了使用Delphi语言与SAP系统交互的完整解决方案,包括源码示例和用户界面设计,通过Remote Function Call (RFC)接口实现数据交换和功能调用。资源包含了SAP系统登录配置、RFC函数调用代码、以及详细的开发流程说明。开发者可利用这些材料学习如何构建Delphi应用程序,以连接到SAP系统,调用其提供的...

weixin_42561464的博客 1195

DELPHI用socket多线程传输文件

DELPHI用socket多线程传输文件

局域网内发送文件的例子(IdUdpClient,IdUdpServer)

=局域网内发送文件的例子(IdUdpClient,IdUdpServer)2007-04-29==============服务端================unit Unit1;interfaceuses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, IdB

记录成长的每一步 4609

delphi使用socket通讯例子-文件传输

delphi使用socket通讯例子-文件传输, delphi使用socket通讯例子-文件传输

DELPHI串口通讯测试资源文件介绍:DELPHI串口通讯全方位教程与实例

DELPHI串口通讯测试资源文件介绍:DELPHI串口通讯全方位教程与实例 去发现同类优质开源项目:https://gitcode.com/ 在当前软件开发领域,串口通讯作为一种传统的通信方式,依然在诸多场景中发挥着重要作用。本文将为您详细介绍一个功能强大的DELPHI串口通讯测试资源文件,帮助DELPHI开发者快速掌握串口通讯技术。 项目介绍 DELPHI串口通讯测试资源文件是一个专为DELPH...

gitblog_06768的博客 374

Delphi7 multipart/form-data实现上传文件

使用indy自带的idhttp控件,用form表单(multipart/form-data)形式上传文件(图片,视频等)

GNSS数据处理新手避坑:手把手教你用GAMP_GOOD下载IGS/MGEX数据(附.cfg文件详解)

本文详细介绍了如何使用GAMP_GOOD进行GNSS数据处理,从基础配置到高级参数调优,帮助新手避开常见错误。内容包括软件安装、配置文件详解、数据源选择、测站文件配置以及性能优化技巧,特别适合GNSS数据处理初学者快速上手。

weixin_30338481的博客 390

DelphiHttps-Post资源文件介绍:Delphi环境下安全的HTTPS POST请求方法

DelphiHttps-Post资源文件介绍:Delphi环境下安全的HTTPS POST请求方法 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在现代软件开发中,网络请求是不可或缺的部分。Delphi Https-Post 资源文件正是为Delphi开发者提供了实现HTTPS POST请求的解决方案。它基于WinINet库,并利用CNPack工具集中的CnMD5和C...

gitblog_06709的博客 650

[南大ICS-PA2]PA2 - 简单复杂的机器:冯诺依曼计算机系统

mips32和riscv32的指令长度只有32位, 因此它们不能像x86那样, 把C代码中的32位常数直接编码到一条指令中. 思考一下, mips32和riscv32应该如何解决这个问题?加载立即数到寄存器的高20位,然后便可以是哟给你标准的立即指令来创建32位常量。在程序分析领域中,静态指令是指程序代码中的指令,动态指令是指程序运行过程中的指令,例如对于一下指令序列。位域,在小端机器上,先定义的在每个字节的低位,后定义的在每个字节的高位。,这是处理非法指令的宏,其定义在。指令,而下一条动态指令则是。

qq_42474104的博客 928

Delphi MQTT客户端资源文件:快速入门与实战指南

Delphi MQTT客户端资源文件:快速入门与实战指南 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在物联网(IoT)和实时通信领域,MQTT协议因其轻量级和高效率而备受青睐。为了帮助Delphi开发者快速掌握MQTT客户端的实现,我们推出了这个Delphi MQTT客户端资源文件。该项目不仅提供了一个完整的MQTT客户端demo,还展示了如何使用Delphi语言...

gitblog_09816的博客 840

AI驱动Spine骨骼动画生成:从图像拆分到动画自动化的全流程解析

计算机视觉与生成式AI技术正深度赋能传统数字内容生产流程。在2D动画制作领域,骨骼动画技术通过模拟真实生物关节运动,实现了角色动画的高效制作与灵活控制。其核心原理在于将角色拆分为独立部件,通过骨骼层级关系驱动部件变换,结合关键帧插值算法生成流畅动作。这项技术的工程价值在于大幅降低动画制作门槛,提升内容生产效率,尤其适用于游戏开发、影视预演、广告设计等需要快速原型迭代的场景。本文聚焦于如何利用SIFT特征匹配、RANSAC几何验证等CV算法实现部件自动对位,并结合动画12原则的程序化实现,构建从单张角色立绘到

weixin_28696185的博客 1516

MPC-CBF 控制原理详解

假设系统满足如下离散时间动力学模型xt1fxtutxt∈Xut∈Uxt1​fxt​ut​xt​∈Xut​∈Uxtx_txt​:状态变量,定义域为可行状态集X⊆RnX⊆Rnutu_tut​:控制输入,定义域为控制约束集U⊆RmU⊆Rm系统需满足安全约束,由如下控制障碍函数(CBF)hX→RhX→RCx∈X∣hx≥0C:=x∈X∣hx≥。

m0_54691290的博客 1179

libeay32.dll与ssleay32.dll Delphi2010 indy10 TLS1.2支持库:安全传输数据的利器

libeay32.dll与ssleay32.dll Delphi2010 indy10 TLS1.2支持库:安全传输数据的利器 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在网络安全日益重要的今天,数据传输的安全性成为开发者关注的焦点。libeay32.dll与ssleay32.dll Delphi2010 indy10 TLS1.2支持库,为您提供了一种高效的解决...

gitblog_06771的博客 909

uniapp [全端兼容] - 实现大文件上传分片/切片+本地选择文件上传超大文件,大文件切片上传+断点续传+上传进度条+失败自动重传,支持单个/批量上传图片、视频、文档各种文件(App、小程序、H5

uniapp 分片 断点续传 大文件上传。uniapp大文件切片上传,uniapp实现大文件上传 分片上传 进度条,分片上传附件,实现大文件上传,实现分片大文件上传,Uniapp实现大文件上传 分片上传 进度条,uniapp文件分片上传,uniapp如何上传很大的文件,在选择文件后,按指定大小将文件切割成独立的文件片,并逐片上传,uniapp 微信小程序上传大文件如何切片,uniapp APP实现大文件分片上传、断点续传、秒传,解决大文件上传问题,大文件上传如何做断点续传,uniapp上传视频,Uniapp

🏆 前端领域优质创作者 1万+

Delphi6/Delphi7 JSON数据解析代码:提升网络开发效率的不二之选

Delphi6/Delphi7 JSON数据解析代码:提升网络开发效率的不二之选 去发现同类优质开源项目:https://gitcode.com/ Delphi6/Delphi7 JSON数据解析代码,助您轻松处理JSON格式数据,提升开发效率。 项目介绍 在当今网络开发领域,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,被广泛应用于服务器与客户端之...

gitblog_06750的博客 1005

eNSP与我这24H2版本不兼容,路由器40错误。这该怎么处理(操作系统-windows)(相关搜索:虚拟机)

🏆本文收录于《全栈Bug调优(实战版)》专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

**My Coding Family** 4109

【大模型应用开发-大模型知识】(二)大模型分类和常见大模型

目前包含 Claude 和 Claude-Instant 两种模型可供选择,其中 Claude Instant 的延迟更低,性能略差,价格比完全体的 Claude-v1 要便宜,两个模型的上下文窗口都是 9000 个token(约 5000 个单词,或 15 页)它的目标是“更安全”、“危害更小”的人工智能。Google 还开发了多种 PaLM 的改进版本。更强大的基础模型: ChatGLM3-6B 的基础模型 ChatGLM3-6B-Base 采用了更多样的训练数据、更充分的训练步数和更合理的训练策略。

1万+

delphi操作文本文件简介

文件是同一类型元素的有序集合,是内存与外设间传输数据的渠道。一些外设如显示器、键盘、打印机等都可以看作文件,但最常用的还是磁盘文件,这也是我们主要讨论的对象。Delphi继承了ObjectPascal的文件管理功能,并有很大的发展,其中最主要的是提供了用于文件管理的标准控件,同时也提供了更多的文件管理函数。利用Delphi的强大功能,开发一个自己的文件管理系统就成为很容易的事。首先介绍Delphi...

linuxstuding 191

ROS 2在自动驾驶中的应用:感知节点开发

ROS 2在自动驾驶中的应用:感知节点开发 ,人工智能,计算机视觉,大模型,AI,本文围绕ROS 2在自动驾驶感知节点开发展开,介绍了ROS 2基础、感知节点开发流程,包括环境搭建、代码编写等,还阐述了常用传感器感知节点开发、多传感器融合,以及测试调试、性能优化、部署集成等内容,分析了开发面临的挑战与未来趋势,为相关开发提供了全面指导,涉及简单代码示例和概念解释。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 14万+
上一篇: (转)Delphi编写WebService体会
下一篇: delphi文件传送
百炼成钢百忍成佛
博客等级 码龄24年 144粉丝 151原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值