HTTP文件下载始末及简单实现

数据库系统概论课后习题答案(第五版 王珊、萨师煊) 第1章 绪论 1 .试述数据、数据库、数据库系统、数据库管理系统的概念。 答: ( l )数据( Data ) :描述事物的符号记录称为数据。数据的种类有数字、文字、图形、图像、声音、正文等。数据与其语义是不可分的。解析在现代计算机系统中数据的概念是广义的。早期的计算机系统主要用于科学计算,处理的数据是整数、实数、浮点数等传统数学中的数据。现代计算机能存储和处理的对象十分广泛,表 阅读详情

        每个人在人生中第一次打开网页时总会迷惑于以http开头的一串字符,网站名很好理解,就好像是门牌号一样,而http://这样的七个字符看起来好像总是那么多余。而所有的浏览器都可以不需要输入那七个字符即可顺利打开网页,当然,事情总是并非表面上看起来那样无足轻重,探究一下事物的始末会发现平静的外表下是无数翻滚的0和1。

        在进入正式的分析前先插入一个前些天的事件。起因是有位小朋友做FTP上传功能,用的是第三方一个现成的类,在传输方法完成之后一段时间内服务器上的文件都还在持续的增长中,直至过了一段时间才完成。他苦恼的是无法判断文件是否传完,我说那就在上传调用结束后定时探测服务器文件长度,一旦和本地文件长度一致就可以认为传完了。小朋友说类里没有这个方法,我告诉他说可以通过FTP协议命令取得,他嗯了一下。过了一会再问我:难道FTP文件可以不用下载到本地就取得长度吗?我忽然明白小朋友最大的问题在于对FTP协议的陌生,所以过分依赖于现有的库或类,我建议他花点时间熟悉一下FTP协议,掌握几个相关的命令就可以实现了。不知道他后来有没有照我说的去做,但我想,他若能尽早了解典型如http此类应用层协议的工作方式,对其他协议的原理就不会那么茫然了。

        如果以一句简单的话来描述浏览器打开页面的原理,那就是通过socket(BSD,POSIX)网络通信方式从WEB SERVER的指定端口(常用80端口)将文件或数据下载至本地,再由浏览器负责解析并呈现。所以无论如何,第一件要做的事情就是把文件或数据依据HTTP协议下载至本地。HTTP协议的英文全称是hyper text transfer protocol,用中文翻着就是超文本传输协议。不必在意其抽象的称谓,在了解一些简单的事实之后会发现http其实是很平易近人的。

        为了讨论的方便,将以静态文件下载说明,而不掺和动态语言脚本phpjspaspxcgi之类的东东了,这些东东的出现其实也是因为当初定义http的那帮大神们没有想到会有这样的应用要求,于是就有了后来的各种动态脚本语言的群魔乱舞了。此处的讨论需要网络通信的基础,所以先对网络通信的基本方法进行说明,而使用的开发语言则是以标准C为摹画。假设我们现在已经配置好一个web server,该server使用80默认端口,我们知道在server上有一个index.html文件,现在要把它下载到本地来。

        若以人类现实行为进行比拟的话,则是首先要向组织提交申请,组织发放一个许可,这个许可就是一个socket句柄:int sock = socket();。获得此许可意味着可以进行下面你想要的操作了,但若组织不予通过,则一定要退出,否则后果自负。第二步是设置被访问的远程主机地址及端口号,这就是说在你出门前先确定要去的地址及门牌号。第三步是建立连接并发送HTTP下载请求,连接是connect()方法,基于TCP协议的连接方式,与之相对的则是UDP,简单来说前者称之为可靠传输,意即发送端会保证接收端按顺序接收完成,后者数据报文协议也称为不可靠连接协议,发送者在发送之后不负责接收端的完整有序接收。第四步是使用recv()方法循环接收数据,因为一个较大的文件一般不会被一次性读到内存中送入发送方法,因为那样非常占用资源,更普遍的做法是多次、分段读取文件,循环送入发送方法。

还是让代码说话吧:

int GetFile(const char *szip, int nPort, const char *szSave)

{

        int nret = -1;

        SOCKET sock = 0;


        do

        {

                sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // 向组织申请通行证

                if ( sock < 0 ) 

                {

                        printf ( "fail socket\n" );

                        break;

                }

                struct sockaddr_in servAddr;

                memset(&servAddr, 0, sizeof(struct sockaddr_in));

                servAddr.sin_family = AF_INET;

                struct hostent *site = NULL;

                

                site = gethostbyname(szip);

                if (site == NULL)

                {

                        printf ( "fail get ip\n" );

                        break;

                }

  //出门前确定好门牌号

                memcpy(&servAddr.sin_addr, site->h_addr_list[0], site->h_length);

                servAddr.sin_family = AF_INET;

                servAddr.sin_port = htons(client.nPort);

  //连接远程服务端

                if (connect(sock, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)

                {

                        printf ( "fail connect\n" );

                        break;

                }

                //发送下载请求,此函数实现在后面给出

                if ( Request((SOCKET)sock, client) < 0)

                {

                        break;

                }

                //将数据保存至文件,实现在后面给出

                nret = SaveFile(sock, szSave);

        }while(0);

 //特别注意:一定要有始有终,用完了,记得要还给组织,不然,还是后果自负。。。

        close(sock);        

return nret;

}

        以上代码段其实更多的是一个基于TCP方式的通用客户端代码框架,也就是说只要服务器是在TCP端口守候的话,就可以这么着初始化、设置、连接、发送数据了。我用的是标准C实现,习惯于其他面向对象语言的同学们一定会念念不忘try--catch机制,而在C中若使用颇有争议的goto必会让学院派们口诛笔伐。所以有一个巧妙的办法,即是do{...}while(0);方式,如果只是单纯看,这仿佛只是一句废话,但它的妙用就在于程序中若出现异常情况时只一句break即可跳出循环,而转到最终清理代码中,而程序运行一切正常时则自然退出此循环。

接下来的Request方法则是特定于HTTP协议的实现。

int Request(SOCKET sock, const char *szFile, const char *szAddress)

{

        int nret = -1;

        char szbuf[1024] = {0};

        sprintf(szbuf,  "GET %s HTTP/1.1\r\n"

                        "Accept: */*\r\n"

                        "Accept-Language: zh-cn\r\n"

                        "User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\r\n"

                        "Host: %s\r\n"

                        "Connection: Close\r\n\r\n", szFile, szAddress);

        

        nret = send(sock, szbuf, (int)strlen(szbuf), 0);

        return nret;

}


 

        都说HTTP是超文本语言,在这个头里终于体现出了文本的意义。没错,这个HTTP头是以文本格式封装的,每行后面的"\r\n"是什么?就是回车换行,我十分怀疑制定HTTP协议的那帮大神们(又提到了他们)当初就是习惯了在命令行下工作,喜欢敲一行命令就回车,然后接着输入下一个命令,把这几个命令给组合完了就叭叭敲两下回车算是提交这个任务了。。。(纯属个人臆测,如有雷同,实属巧合)。当然,头部信息的内容不止上文代码中那些,但第一个大写的GET即是说要把东西取回来,文件名紧跟在GET之后。其他的参数则是说协议版本、本地语言、主机地址、是否保持连接等。Web Server在收到这样一个文本字符串之后即解析请求内容将文件发回客户端。在此要说明另一个关键命令POST,大概有不少做了N年WEB开发的同学们并不真的能说清GET和POST的区别,反正参数不长的就用GET方法提交,参数内容太长的就用POST方法提交。现在我们知道了,POST是发送,它与GET相对,一个是下载,一个上传,就这么简单。而GET之所以不能在?后面的参数写太长,是因为它是放在HTTP头部里提交,这个长度是有限制的,超出了这个限制自然会认为请求出错。而POST发送时要在头部中写明待上传数据字节数,并且上传数据跟在两个回车换行之后,所以再长的数据也能发送上去。现在想想大神们有时候想法也是挺简单的,但人家厉害就在把复杂的事情简单化,我们凡人恐怕简单的事情也要复杂化。

下面是从HTTP返回的数据中保存为文件。

#define  MU_PACK_LEN  32768

int SaveFile(SOCKET sock, const char *szfile)

{

        char *ptr = NULL;

        char buf[MU_PACK_LEN] = {0};

        int  nlen = 0;

        int  nheadlen = 0;

        int  nfilelen = 0;

        int  nputlen  = 0;

        int  ndownlen = 0;

        const char szHeadTag[] = "\r\n\r\n";//传说中的两下回车,文件数据是跟在这个标识之后。

        FILE *fp = NULL;

        int nret = -1;

        do

        {

  //接收服务端返回数据

                nlen = recv(sock, buf, MU_PACK_LEN, 0); 

                nputlen = nlen;

                ptr = buf;

                if (nheadlen <= 0)

                {

      //下面的内容是说文件数据有没有和头部数据放一块返回,据我的测试大部分Web server都是放一块返回,但仍然还有server是先返回头部数据,再发送文件数据。

                        ptr = strstr(buf, szHeadTag);

                        if (ptr)

                        {

                                ptr += strlen(szHeadTag);

                                nheadlen = (int)(ptr - buf);

//从HTTP头部中取得待下载文件长度,所以,如果你仅是想知道一个在HTTP服务器上的文件长度是多少的话,取完了这个值你就可以直接关闭socket了。代码在后面给出。

                                nfilelen = GetFileLenFromHead(buf); 

                                nputlen  = nlen - nheadlen;

                                if (nheadlen == nlen && nfilelen > 0)

                                {

                                        continue;

                                }

                        }

                }

                if ( !fp && nfilelen > 0)

                {

                        fp = fopen(szfile, "wb");

                }

  //来一段数据就写一段到文件中

                if (nlen > 0 && nfilelen > 0)

                {

                        fwrite(ptr, nputlen, 1, fp);

                        memset(buf, 0, MU_PACK_LEN);

                        ndownlen += nputlen;

                }

                else

                {

                        break;

                }

                

        }while(nlen > 0);

        if (fp)

        {

                fclose(fp);

        }

        if (ndownlen == nfilelen && nfilelen > 0)

        {

                nret = 0;

        }

        else

        {

                cout << "down len: " << ndownlen << endl;

                cout << "file len: " << nfilelen << endl;

        }

        

        return nret;

}

取得文件长度功能。
int  GetFileLenFromHead(const char *phead)

{

        char *plen = NULL;

        int nret = -1;

        const char szLenTag[]  = "Content-Length: "; //文本标识,在这个冒号后面的是一个十进制的数字,以一个回车换行为结束。

        int i = 0;

        char szvalue[32] = {0};

        plen = strstr(phead, szLenTag);

        if (plen)

        {

                plen += strlen(szLenTag);

                while(plen[i] != '\r')

                {

                        szvalue[i] = plen[i];

                        i++;

                }

               nret = atoi(szvalue);

        }

        return nret;

}

        以上代码只是一个简单实现,工程应用中还有很多细节需要注意,服务器返回的头部文本在此并未展示,只是给同学们一个悬念吧,有兴趣的话看看那到底是一串什么东东。(我能提点意见么,这个发布文章的编辑区也太不好用了吧,行首按下TAB键整段漂移。。不知道预览功能在哪,一定要发布以后才能看到整个文章的排版。最假的还是登录机制,我先是在IE上,退出以后发现排版不对想重新登录,输入密码后倒是通过了,可进入博客却怎么都是未登录状态,换一个浏览器chrome又可以正常登录,疯狂的崩溃中,这就是程序员做的网站么,这不得让那一大帮子大牛们笑翻滚了么。。。)

抖音直播间人气接口算法 抖音协议 抖音直播间人气接口算法 抖音协议 抖音算法 阅读详情

相关推荐

实测有效!YOLOv8融合EMA注意力机制后,在无人机航拍目标检测中的性能提升对比

本文详细介绍了YOLOv8融合EMA注意力机制在无人机航拍目标检测中的性能提升效果。通过多尺度特征融合和通道-空间双重注意力机制,EMA模块显著提升了小目标检测的准确率,mAP@0.5平均提升4.2%,同时保持推理速度基本不变。文章还提供了模型定制、训练技巧和实际部署优化的全流程指南。

weixin_33704234的博客 391

http协议及基于http协议的文件下载

目录 1. HTTP 协议概述 2. URL 与资源 3. HTTP报文 4. 使用Postman 获取数据 5. 基于HTTP协议的文件下载 5.1 文件整体下载 5.2 文件分段(Range)下载 5.2.1 获取文件的大小 5.2.2 下载分段文件 5.3 文件分块(chunk)下载 1. HTTP 协议概述 日常我们使用网络用得最多的无疑是在Web 浏览器(下文统...

Xanthium 2万+

基于Codex/Claude Code的学术技能包:13个Skill实现科研全流程自动化

写论文最头疼的是什么?是面对海量文献无从下手,还是实验数据一团乱麻,或者是好不容易有了结果,却卡在写作和格式调整上?如果你也经历过从选题到投稿的完整科研周期,就会明白每个环节都可能消耗大量时间精力。今天要分享的这套工具链,正是为了解决这些痛点而生——基于 Codex 和 Claude Code 平台的学术技能包(Academic Skills),它通过 13 个精心设计的 Skill,将一篇论文从 0 到 1 的全流程自动化、标准化,让你能更专注于研究本身。 这套技能包并非单一工具,而是一个覆盖文献阅读、数

weixin_33979203的博客 542

http 协议大文件下载

响应的正文只能通过http响应消息进行传输,如果是小文件(比如小于1M)传输,则没有什么问题,直接把文件内容加载到正文进行回应即可,但如果是大文件(比如大于10M),不可能把文件内容加载到正文吧,如果更大的文件呢,100M?下载一个 19 M 的文件是可以成功的,再大的文件没有试,因为下载速度有点慢。那下载下来的文件是否有异常呢?windows上下载的,所以把这个文件拷贝到 CentOS 服务上看一下了,这两个文件经过 md5sum 后值是一样的,那我们下载的文件就是正常的。那用c++代码怎么写呢?....

tianyexing2008的博客 5619

手把手教你用Ubuntu 22.04的附加驱动工具安装NVIDIA显卡驱动(含常见错误修复)

本文详细介绍了在Ubuntu 22.04系统上,如何通过图形化的“附加驱动”工具安全、便捷地安装NVIDIA显卡驱动。内容涵盖从准备工作、禁用默认的nouveau驱动、图形界面安装实操,到安装后的验证(如使用nvidia-smi命令),并提供了安装失败黑屏、亮度调节失效等常见问题的深度解决方案,帮助用户彻底搞定驱动安装难题。

weixin_29248653的博客 602

Python爬虫实战:手把手教你用Selenium绕过药监局网站的反爬机制(附完整代码)

本文详细介绍了如何使用Selenium绕过药监局网站的反爬机制,提供了一套完整的Python爬虫实战方案。通过浏览器指纹伪装、动态等待策略、会话维持技巧以及分布式采集设计,帮助开发者高效爬取药监局数据,解决政府类网站常见的反爬挑战。

weixin_42620255的博客 738

JAVA用http协议实现简单文件下载

用http协议实现一个简单的网络资源下载文件! 研究大文件断点传输的时候,梳理自己的思路,写了一个http协议的文件下载的demo,非常简单,但是能够实现! 上代码: public class FileDown { InputStream inputStream; public void Filee(){ try { //新建URL对象 ...

小轩的名古屋 4714

STM32驱动HC-SR04超声波模块:两种精准测距方案详解

本文详解STM32驱动HC-SR04超声波模块的两种精准测距方案:定时器中断计数法和外部中断边沿检测法。涵盖硬件连接、代码实现与优化技巧,帮助开发者根据精度和复杂度需求选择合适方案,提升超声波测距在嵌入式项目中的稳定性和准确性。

g5h6i的博客 684

HTTP服务器发送RST报文给客户端,是什么原因?

HTTP服务器发送RST报文给客户端的原因可能是因为服务器已经关闭了与客户端的连接,或者是因为服务器检测到了异常状态。

weixin_35755434的博客 639

【WorkBuddy专栏61】字节的AI打法为什么一直在变——WorkBuddy/CodeBuddy vs 字节Trae/TRAE Work/豆包全维度对比

【WorkBuddy专栏61】字节的AI打法为什么一直在变——WorkBuddy/CodeBuddy vs 字节Trae/TRAE Work/豆包全维度对比

AI人人懂 2762

【WorkBuddy专栏50】代码开发技术体系深度分析——前端、后端、全栈、移动端、数据工程,WB和CODEBUDDY谁更擅长?

【WorkBuddy专栏50】代码开发技术体系深度分析——前端、后端、全栈、移动端、数据工程,WB和CODEBUDDY谁更擅长?

AI人人懂 237

docker es搭建 始末

公司最近使用es 本地搭一套走起。 docker如果没有可以自行下载(https://www.runoob.com/docker/centos-docker-install.html) 一、es安装 1、下载es docker pull docker.elastic.co/elasticsearch/elasticsearch:5.5.3 (注意版本、最好和公司的一致) 2、启动镜像 docke...

奕鸣的博客 336

H3C BGP联盟实验

bgp,bgp联盟,bgp公认团体属性,

一只懒羊羊 970

程序员离职事件始末

点击上方“码农突围”,马上关注,每天早上8:50准时推送真爱,请置顶或星标本文转载自公众号:程序员吴小胖这是我毕业后的第一份工作...面试时,HR小姐姐告诉我...然鹅....

欢迎关注公众号:【码农突围】,公号后台回复9999,可以获取一份500页的LeetCode刷题笔记。 332

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【爬虫】初学爬虫,了解始末(概念类—更新中)

因为对堆糖的图片心心念念,但是目前从网上翻出来的爬虫代码没有能够做到将大图保存下来的,所以决定自学爬虫,直到完成堆糖的大图片的下载(*^▽^*) 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。 传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽...

无水wangyang 279

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

html5的本地缓存优化,缓存、优化、http

总结几个常见的问题,贯穿前端学习的始末。1.浏览器本地存储在较高版本的浏览器中,js提供了sessionStorage和globalStorage。在HTML5中提供了localStorage来取代globalStorage。html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage。sessionStorage用于本地存储一个会话(sessio...

weixin_33609486的博客 240

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【SSL证书】IOS的春天乍暖还寒,仍需HTTPS的温暖

这个春天忽冷忽热,正如IOS ATS带给大家的感觉一样,去年在IOS上拥有APP的和想在IOS上上线APP的企业及个人都被强制ATS这股风潮吓了一哆嗦,认为过不去今年1月1号ATS这一关了。但温暖悄然来临,IOS推迟了强制ATS的计划,但这个“春天”确是乍暖还寒,因为只是推迟不是废除,因此,IOS的春天仍需HTTPS加密的温暖! 回顾IOS强制APP通过ATS限制策略始末 在2016年...

xinyuan82的博客 1

fresh-start 与 HISTORY.md 全解:Claude Code 源码泄漏事件始末与 x402「隐藏钱包」误报澄清

本文以 fresh-start 仓库根目录的 [HISTORY.md](https://link.gitcode.com/i/6b347942b6fa87d0afea678fbe387fea) 为绝对主体,完整还原 2026 年 3 月 31 日 Claude Code 源码泄漏事件的全过程:泄漏如何发生、DMCA 下架如何执行与部分撤回、以及一个至今仍被搜索引擎当作"事实"重复的误报——Clau

gitblog_00997的博客 163

SQLModel 更新数据记录实战指南

在 SQLModel 里改一条数据库记录,不用手写 UPDATE 语句:把查出来的对象当普通 Python 对象改属性,再 `add` + `commit`,变更就写回数据库了。这套 Python ORM 更新流程能覆盖单条修改、批量提交、校验拦截和并发保护这几类高频需求,学完可以直接拿去写"只更新用户提交字段"的接口,也能处理上千条记录的机械更新。 ## 最小可运行的单条记录更新 先看官方教

gitblog_00878的博客 325

Egg/Tegg Standalone Service Worker 深度指南:无需 Egg 应用,用 Fetch 语义运行 HTTP 控制器与 MCP 工具

本文围绕 tegg 生态中的 **Standalone Service Worker** 运行时(`@eggjs/service-worker` 及其配套包)展开,讲解如何在不启动 Egg 应用的前提下,基于 Fetch API 语义直接从 tegg 模块中提供 HTTP 控制器与 MCP(Model Context Protocol)工具。读完本文,你将掌握:三包分工与四层控制器架构、应用目录与

gitblog_00907的博客 238

Python学习教程:这里是Python爬虫的起点,抢占资源啦

今天跟大家出的这篇文章,是从爬虫的起点开始讲起,这里的Python学习教程,一篇文章带你贯穿爬虫始末!之前也够跟大家出过相关的Python相关的Python学习教程,伙伴们也可以翻阅一下以前的! 爬虫系列文章的第一篇,这里便为大家讲解了HTTP原理,很多人好奇:好好的讲爬虫和HTTP有什么关系?其实我们常说的爬虫(也叫网络爬虫)就是使用一些网络协议发起的网络请求,而目前使用最多的网络协议便是HT...

chen801090的博客 305

模型地址变数据通道:Open WebUI攻击链5秒权限接管与CVE被拒始末

在自托管AI服务中,模型地址本质上是一条数据通道,而非简单的URL字符串。当管理员配置第三方模型API时,服务器会主动请求远端端点,并将返回的JSON视为可信配置解析使用。若攻击者构造恶意模型响应,可注入指令或劫持工具调用机制,将模型输出转化为特权操作,最终实现读取环境变量、获取后台密钥并完成权限接管。整个过程仅需数秒,且流量形态与正常API交互无异,常规安全设备难以察觉。这种信任边界被不合理跨越的问题,虽常因“需要管理员主动配置”而被CVE审核方拒绝受理,但其真实危害不容忽视。本文通过完整拆解从模型地址配

weixin_32377497的博客 245

好记性不如烂笔头--linux学习笔记9练手写个shell脚本

好记性不如烂笔头--linux学习笔记9练手写个shell脚本 #!/bin/bash #auto make install httpd #by authors baker95935 2017 #httpd define path variable ...

weixin_30340775的博客 196

云端文件上传实战指南:从Colab到OSS的跨平台策略与优化

文件上传是数据持久化与系统交互的基础操作,其核心原理涉及客户端与服务器之间的网络传输协议。通过理解HTTP、分块上传及断点续传等机制,开发者可以构建更可靠、高效的数据管道,这对于提升应用性能和用户体验至关重要。在云端协作、AI训练、资源管理等应用场景中,针对不同平台特性选择合适的上传策略尤为关键。例如,在Google Colab中,通过挂载Google Drive实现持久化存储;在阿里云OSS中,利用签名后表单直传技术可绕过应用服务器,实现安全高效的文件直传。掌握这些核心技巧,能有效解决大文件传输、跨平台同

879

这里是Python爬虫的起点,抢占资源啦(Python学习教程)

今天跟大家出的这篇文章,是从爬虫的起点开始讲起,这里的Python学习教程,一篇文章带你贯穿爬虫始末!之前也够跟大家出过相关的Python相关的Python学习教程,伙伴们也可以翻阅一下以前的! 爬虫系列文章的第一篇,这里便为大家讲解了HTTP原理,很多人好奇:好好的讲爬虫和HTTP有什么关系?其实我们常说的爬虫(也叫网络爬虫)就是使用一些网络协议发起的网络请求,而目前使用最多的网络协议便是HT...

XIAOYUE3035的博客 1640

SITS2026突发技术快报:凌晨发布的MoE-32K模型权重泄露事件始末,及企业级防御加固清单(含YAML配置模板)

紧急应对MoE-32K模型权重泄露,提供企业级防御加固方案与YAML配置模板。适用于AI研发、安全运维场景,兼顾实效性与可落地性。AI技术大会现场直播:SITS2026在线观看同步解读事件始末,值得收藏。

LiteCode的博客 329
上一篇: C++如何调用delphi制作的dll
下一篇: 14, bad address
程序猿阿诺
博客等级 码龄23年 25粉丝 79原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值