Linux下Socket写http协议下载文件代码以及说明

手写Socket Web服务器:深入HTTP协议底层原理 HTTP协议是Web通信的基石,其本质是一套严格定义的文本格式与状态交互规范。理解它需回归传输层——TCP连接建立、请求响应格式(如状态行、头/体分隔符\r\n\r\n)、字符编码与字节长度一致性等核心原理。这些知识直接决定CORS拦截、中文乱码、Content-Length错误等高频问题的排查效率。在现代框架封装日益厚重的今天,亲手用Socket实现一个可被Chrome识别的极简Web服务器,成为掌握Web运行机制最有效的实践路径。本文即以DebugLZQ经典案例为蓝本,还原从URI解析、DNS查询、So 阅读详情


看代码:

          #include <string>   
  1. #include <iostream>   
  2. #include <stdio.h>   
  3. #include <winsock.h>   
  4. #include <conio.h>   
  5.   
  6.   
  7. using namespace std;   
  8.   
  9. #pragma comment("ws2_32.lib")   
  10.   
  11. string host2ip(const string& strdomain);   
  12. void save2file(char *buffer,const string& filename);   
  13. int getlength(const string& sheader);   
  14. bool getstatus(const string& sheader);   
  15. int getleftlength(const string& sheader);   
  16. void sethttphead(const string& file,const string& server);   
  17.   
  18.   
  19. int port = 80;   
  20. int error=0;   
  21. string serveraddr;   
  22. int i = 0;   
  23. const int BUFFER_SIZE = 1024;   
  24. char buffer[BUFFER_SIZE] = {0};   
  25. char    msg[BUFFER_SIZE];   
  26. FILE *f;   
  27. const string file = "/BT/200801/3/117906.torrent";   
  28. const string url = "www.supbt.com";   
  29. const string filename = "117906.torrent";   
  30.   
  31.   
  32. int main(void)   
  33. {   
  34.         int      r;   
  35.         WSADATA  wsa;   
  36.         SOCKET   sock;   
  37.         struct   sockaddr_in sin;   
  38.         f = fopen(filename.c_str(),"ab");   
  39.         sethttphead(file,url);   
  40.         if(WSAStartup(MAKEWORD(2,2),&wsa))   
  41.         {   
  42.                 printf("WSAStartup Error: %d/n",WSAGetLastError());   
  43.                 getche();   
  44.                 return -1;   
  45.         }   
  46.   
  47.         if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)   
  48.         {   
  49.                 printf("Socket Error: %d/n",WSAGetLastError());   
  50.                 getche();   
  51.                 return -1;   
  52.         }   
  53.      
  54.         sin.sin_family=AF_INET;   
  55.         sin.sin_port=htons(port);   
  56.         serveraddr = host2ip(url);   
  57.   
  58.         cout << serveraddr << endl;   
  59.         sin.sin_addr.s_addr=inet_addr(serveraddr.c_str());   
  60.      
  61.   
  62.         if(connect(sock,(struct sockaddr *)&sin,sizeof(sin))==SOCKET_ERROR)   
  63.         {   
  64.                 printf("Connect Error: %d/n",WSAGetLastError());   
  65.                 printf("请检测网络连接!/n");   
  66.                 getche();   
  67.                 return -1;   
  68.         }   
  69.   
  70.      
  71.         if((r=send(sock,msg,sizeof(msg),0))==SOCKET_ERROR)   
  72.         {   
  73.                 printf("Send Error: %d/n",WSAGetLastError());   
  74.                 getche();   
  75.                 return -1;   
  76.         }   
  77.   
  78.         memset(buffer,0,BUFFER_SIZE);   
  79.         if((r=recv(sock,buffer,BUFFER_SIZE,0))==SOCKET_ERROR)   
  80.         {   
  81.                 printf("Recv Error: %d/n",WSAGetLastError());   
  82.                 closesocket(sock);   
  83.                 return -1;   
  84.         }   
  85.   
  86.         string header = string(buffer);   
  87.         int ilength = getlength(header);   
  88.         int leftlength = ilength;   
  89.         int icount;   
  90.         if(getstatus(header)){   
  91.                 //current is r   
  92.                 char *q = buffer;   
  93.                 char *p = strstr(buffer, "/r/n/r/n");   
  94.   
  95.                 p += 4;   
  96.                 //注意这里得 r - (p-q) 非常关键得问题   
  97.                 fwrite(p,r - (p - q),1,f);   
  98.                 leftlength -= r - (p - q);   
  99.                 int i=0;   
  100.                 icount = r - (p - q);   
  101.                 while(true)   
  102.                 {   
  103.                         memset(buffer, 0, BUFFER_SIZE);   
  104.                         r = recv(sock, buffer, BUFFER_SIZE, 0);   
  105.   
  106.                         if (r < 0) {   
  107.                                 closesocket(sock);   
  108.                                 return 2;   
  109.                         }   
  110.                         if (r == 0) {   
  111.                                 break;   
  112.                         }   
  113.                         int tmp;   
  114.                         tmp = leftlength;    //209  100 100 92   
  115.                         leftlength -= r;   
  116.                         if(leftlength > 0){   
  117.                                 fwrite(buffer,r,1,f);   
  118.                                 icount += r;   
  119.                         }   
  120.                         else if(leftlength == 0){   
  121.                                 //   
  122.                                 break;   
  123.                         }   
  124.                         else{   
  125.                                 icount += tmp;   
  126.                                 fwrite(buffer,tmp,1,f);   
  127.                                 break;   
  128.                         }   
  129.                         cout << i++ << " r is "<< r << endl;   
  130.   
  131.                 }   
  132.         }else{   
  133.                 cout << "http protocal error" << endl;   
  134.         }   
  135.         cout << icount << endl;   
  136.         fclose(f);   
  137.         closesocket(sock);   
  138.         WSACleanup();   
  139.         getche();   
  140.         return 0;   
  141. }   
  142. /*  
  143. 构造HTTP头  
  144. */  
  145. void sethttphead(const string& file,const string& server)   
  146. {   
  147.         strcat(msg,"GET ");   
  148.         strcat(msg,file.c_str());   
  149.   
  150.         strcat(msg," HTTP/1.1");   
  151.         strcat(msg,"/r/n");   
  152.   
  153.         strcat(msg,"Accept:*/*");   
  154.         strcat(msg,"/r/n");   
  155.   
  156.         //strcat(msg,"Accept-Language: zh-cn");   
  157.         //strcat(msg,"/r/n");   
  158.   
  159.         //strcat(msg,"Accept-Encoding: gzip, deflate");   
  160.         //strcat(msg,"/r/n");   
  161.   
  162.         strcat(msg,"User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");   
  163.         strcat(msg,"/r/n");   
  164.   
  165.         strcat(msg,"Host:");   
  166.         strcat(msg,server.c_str());   
  167.         strcat(msg,"/r/n");   
  168.   
  169.         strcat(msg,"Connection: Keep-Alive");   
  170.         strcat(msg,"/r/n");   
  171.         strcat(msg,"/r/n");   
  172. }   
  173. //---------------------------------------------------------------------------   
  174.   
  175. /*   
  176. 将domain 转换为IP地址   
  177. */   
  178. string host2ip(const string& strdomain)   
  179. {   
  180.         SOCKADDR_IN   saddr;   
  181.         WORD   wVersionRequested;      
  182.         WSADATA   wsaData;      
  183.         hostent   *pHostIp;   
  184.         int   nErrorNum;      
  185.         wVersionRequested   =   MAKEWORD(2,   2);      
  186.         nErrorNum   =   WSAStartup(wVersionRequested,   &wsaData);   
  187.         if(nErrorNum   !=   0)   
  188.         {   
  189.                 return   "";   
  190.         }   
  191.         saddr.sin_family   =   AF_INET;   
  192.         pHostIp   =   gethostbyname(strdomain.c_str());   
  193.         if(pHostIp   ==   NULL)   
  194.         {   
  195.                 return   "0.0.0.0";   
  196.         }   
  197.         WSACleanup();   
  198.         return   (string)inet_ntoa(*(LPIN_ADDR)*(pHostIp->h_addr_list));   
  199. }   
  200. /*  
  201. 该方法为测试用法,并为应用到项目中  
  202. */  
  203. void save2file(char *buffer,const string& filename)   
  204. {   
  205.         FILE *f;   
  206.         f = fopen(filename.c_str(),"a+");   
  207.         fwrite(buffer,strlen(buffer),1,f);   
  208.         fclose(f);   
  209. }   
  210. /*  
  211. 该方法获取待下载文件大小  
  212. */  
  213. int getlength(const string& sheader){   
  214.         char * cont_len_pos;   
  215.         unsigned long cont_length;   
  216.         const char* header = sheader.c_str();   
  217.   
  218.         cont_len_pos =(char *)strstr(header,"Content-Length:");   
  219.         cont_len_pos = (char *)strchr(cont_len_pos,' ');   
  220.         cont_len_pos++;   
  221.         sscanf(cont_len_pos, "%ld", &cont_length);   
  222.   
  223.         return cont_length;   
  224. }   
  225. /*  
  226. 该方法判断是否Get成功,不成功就取消下载文件  
  227. */  
  228. bool getstatus(const string& sheader){   
  229.         string start = "HTTP/1.1 200 OK";   
  230.         if(sheader.find(start,0) != string::npos){   
  231.                 return true;   
  232.         }   
  233.         else{   
  234.                 return false;   
  235.         }   
  236. }   
  237. /*  
  238. 该方法并没有用到,开始考虑多了  
  239. */  
  240. int getleftlength(const string& sheader){   
  241.         int nreturnl = 0;   
  242.         int ilength = sheader.length();   
  243.         string _send = "/r/n/r/n";   
  244.         int istart = sheader.find_last_of(_send);   
  245.         if(istart != string::npos){   
  246.                 nreturnl = ilength - istart -_send.length();   
  247.         }   
  248.         return nreturnl;   
  249. }   
语言随机效应模型_线性混合效应模型 VS 方差分析 线性混合效应模型相比方差分析具有很多优点。为了让大家更直观的了解,我们来做一下两者的对比。基于模拟的方法,生成了以下数据dat_sim:这种数据格式是长格式,也就是从实验软件导出来的那种数据格式。这种数据格式可以直接使用线性混合效应模型进行分析。该实验设计是被试内项目间的单因素两水平设计。category是自变量,两个水平分别是outgroup和ingroup,outgroup比ingr... 阅读详情

相关推荐

(MIUI)小米手机录音文件深度寻踪:从系统缓存到数据目录的实战解析

本文深入解析了MIUI系统中录音文件丢失的常见原因及解决方案,包括系统升级兼容性问题、应用缓存机制异常和存储权限变动。通过实战操作指南,详细介绍了如何从系统目录、数据库层面恢复录音文件,并提供了预防措施和自动化备份方案,帮助小米手机用户有效找回重要录音数据。

weixin_42699679的博客 518

HTTP下载新功能研究

W5500的时候是OK的每次下来不会超过2049个数据 但是ESP8266看到一次过来2092个数据 装不下! 单片机内存吃紧 研究HTTP执行下载的时候对一个参数! 第一步:http://ibinhub.com/login.php上传一个文件 后面开始PC茉莉 发送: #define HTTP_POST "POST /data.php HTTP1.1\r\...

GKoSon的博客 360

混合编程实战:C#集成C++ PCL点云处理库,打造跨语言动态链接库

本文详细介绍了C#与C++混合编程实战,重点讲解如何通过动态链接库(DLL)集成C++ PCL点云处理库,实现跨语言协作。内容涵盖环境配置、PCL功能封装、C#调用DLL的完整方案,以及性能优化和错误处理等进阶技巧,帮助开发者高效处理大规模点云数据,提升工业软件开发效率。

weixin_42620913的博客 382

lwip接收文件 stm32_stm32 lwip 如何访问网页下载文件

int BIN_currentlen_left ( char * recv_data ){intlen ;char data_buf[60];/*缓存*/char cache_buf[20];/*缓存*//*1、在接收到服务器的数据后,查找"Content-Range: bytes"字段,并返回数据地址*//*2、在接收到服务器的数据后,查找"\r\n"字段,并返回数据地址*//*3、获取长度...

weixin_42297446的博客 1032

当LightGBM推理遇上GPU:3种替代方案性能对比(含ONNX实战代码)

本文针对LightGBM官方不支持GPU推理的性能瓶颈,深度评测了RAPIDS cuML、ONNX Runtime GPU和Triton Inference Server三种GPU加速推理替代方案。通过详尽的性能对比和实战代码,为高并发、低延迟的在线预测场景提供了清晰的选型指南,帮助工程师打破推理性能枷锁,实现显著的吞吐量提升。

salt9的博客 813

主流算力卡性能对比分析

超大规模AI训练/HPC:优先选择NVIDIA H100或AMD MI300X,需关注显存带宽和多卡互联能力。企业级AI训练:NVIDIA A100性价比更高,生态成熟。国内自主可控需求:华为昇腾910B是首选,支持液冷和低功耗设计。本地AI推理/游戏:NVIDIA RTX 4090或RTX 5090性价比突出,但需注意显存容量限制。边缘计算/低功耗场景:华为昇腾310或清微智能TX536(能效比6.3TOPS/W@INT8)更合适。

m0_69867914的博客 7805

linux C++ HTTP 下载文件 dowloadFile()

DownLoadFIle(std::string serverName, std::string URL,std::string localDirectory) { FILE *fp;     if(!(fp = fopen(localDirectory.c_str(),"wb+")))     {         printf("can't open loc

KEN Bolg 7118

CPU系统级验证——测试激励——imperas公司riscvOVPsimPlus文件分析

本分析重点关注该repo向量扩展部分。 1. repo简介 该repo是指令集验证的仿真环境包括,大部分是指令集的测试用例,也包含了一些模拟器,如riscvOVPsimPlus。 主要介绍的是riscvOVPsimPlus指令集模拟器,riscvOVPsimPlus(下面统称ISS)是imperas公司在riscvOVPsim基础上扩充了向量扩展的指令集模拟器,该repo于今年9月份部分开源 什么叫部分开源呢? 首先该repo必须在imperas官网注册下载,而且必须是企业用户(免费邮箱人家瞧不上.

知识,既贵,又便宜。 4460

Linux下使用Socket实现http文件下载

Linux linux// 转载自 http://blog.youkuaiyun.com/xiongyangg/article/details/50767482 // g++ download_demo.cpp -lpthread #include <stdio.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #incl

Ataraxia的专栏 4253

Unidbg逆向阿里系App签名:从环境补全到算法还原实战

在移动安全与协议分析领域,理解应用层签名机制是核心挑战之一。签名算法作为保障通信安全与身份验证的关键技术,其原理通常涉及哈希、加密及密钥协商等基础密码学概念。在Android平台,核心签名逻辑常被加固并隐藏于Native层SO库中,以对抗动态调试与静态分析,这为安全研究和协议兼容带来了技术障碍。Unidbg作为一种基于模拟执行的逆向工程工具,通过模拟ARM指令集和系统调用,允许研究者在脱离真机环境的情况下,可控地执行和调试SO文件,为解决此类问题提供了创新思路。其技术价值在于实现了对加固代码的确定性分析与算

weixin_42525738的博客 939

基于DWA算法的机器人动态避障技术实现及matlab代码

DWA算法是一种基于轨迹的运动规划算法,其核心思想是:在机器人当前位置及速度的基础上,结合机器人感知到的环境信息,生成一组合法的速度指令,然后从这组速度指令中选取代价最小的速度指令作为机器人的下一步操作。下面,我们将通过一个实例来演示基于DWA算法的机器人动态避障技术实现。假设机器人在一个宽敞的场地内行驶,但场地内有一些固定障碍物和移动障碍物,机器人需要避开这些障碍物,并在场地内自由移动。本文给出了一种基于DWA算法的机器人动态避障技术实现及相应的matlab代码,读者可以根据自身需求进行修改和调整。

uote_e的博客 1003

C++实现HTTP文件下载:从Socket到分块编码的完整实践

HTTP协议作为互联网数据交换的基石,其核心在于客户端与服务器之间基于请求-响应的通信模型。理解其工作原理,不仅需要掌握状态码、请求头、响应头等基本概念,更需要深入网络编程层面,通过Socket编程实现数据的可靠传输。对于追求极致性能或需要在资源受限环境中运行的场景,直接使用底层API进行开发具有重要价值,它能实现对内存、连接和I/O的精细控制。例如,在处理大文件下载或需要实现断点续传、分块传输编码解码等高级特性时,这种底层控制能力尤为关键。本文通过一个具体的C++项目,详细展示了如何从零开始,使用Wins

weixin_30617695的博客 503

信号处理算法:自适应滤波_(8).自适应陷波器

自适应陷波器是一种强大的工具,广泛应用于电力系统、通信系统和生物医学信号处理等领域。通过自适应调整滤波器的参数,自适应陷波器可以在特定频率处形成陷波,从而有效地抑制噪声或干扰信号。常见的自适应算法包括LMS和RLS,它们各有优缺点,可以根据实际需求选择合适的算法。

2401_87715305的博客 1371

推荐两篇Linux下的Socket文章

Linux Socket Linux下Socket编程 HTTP 协议的简介 HTTP 协议的简介    HTTP协议是一种超文本传输协议(Hypertext Transfer Protocol),工作于网络应用层,自1990年起广泛应用于WWW 的全球信息服务,HTTP协议的详细说明可以在网上查阅RFC2518、RFC2616等文档。    HTTP 协议老的标准是HTTP

benpaobagzb的博客 2702

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【Linux之旅】HTTP 协议解析:从请求格式到构建 Web 服务器

本文将从 HTTP 协议的请求/响应格式出发,逐一拆解 URL、请求方法、状态码、常用 Header、Connection 长连接等核心概念,亲手实现一个支持 GET 和 POST 的最简 HTTP 服务器,并逐步扩展为能返回静态文件、解析表单数据的功能完备的 Web 服务器。读完本文,你将彻底理解 HTTP 协议的底层约定,并能从头写出一个可被浏览器访问的真实 Web 后端。

2302_80243065的博客 2328

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

【Linux网络】深入理解 HTTP 协议(四):完善 C++ HTTP 服务器:从协议原理到生产级实现

HTTP 协议作为 Web 世界的基石,支撑着我们每天浏览的每一个网页、调用的每一个 API。虽然 Nginx、Apache 等成熟服务器已经足够强大,但亲手实现一个 HTTP 服务器,能让我们穿透抽象层,真正理解 “浏览器输入 URL 按下回车” 背后发生的一切。本文将从 HTTP 协议最核心的 GET/POST 请求讲起,一步步拆解 HTTP 服务器的分层架构,实现一个支持静态资源托管、动态路由注册、完整协议解析的 C++ HTTP 服务器。然后我们会深入讲解Nginx 生产级部署的最佳实践,最后对比自

会当凌绝顶,一览众山小 5295

500行代码构建完整HTTP服务器:Tinyhttpd终极学习指南

Tinyhttpd是J. David Blackstone在1999年编写的超轻量级HTTP服务器,整个项目代码不到500行,却完整实现了HTTP服务器的核心功能。这个项目被誉为学习网络编程和HTTP协议的经典教材,通过极简的代码展示了服务器程序的本质。无论你是网络编程初学者还是想深入理解HTTP协议实现原理的开发者,Tinyhttpd都能为你提供宝贵的实践机会。 ## 🔥 项目核心亮点:为什

gitblog_01152的博客 983

UDP vs TCP:Linux Socket编程中的协议选择指南

UDP和TCP各有优劣:UDP以速度取胜,适合实时和轻量级应用;TCP以可靠性为核心,适合数据敏感场景。在Linux Socket编程中,根据应用需求(延迟容忍度、数据大小、网络条件)做出明智选择。始终通过原型测试验证性能(如使用iperf工具),确保最佳用户体验。

2501_93878031的博客 1720

C++多线程断点续传下载器实现:从HTTP协议到工程实践

在并发编程和网络应用开发中,多线程技术与断点续传机制是提升系统性能和可靠性的核心概念。多线程通过并行处理任务,充分利用多核CPU资源,显著提高I/O密集型操作的效率;而断点续传则基于HTTP协议的Range请求头实现,允许在传输中断后从中断处继续,避免重复下载,增强了应用的健壮性。这两项技术的结合,在文件传输、数据同步等场景中具有重要价值。本文聚焦于C++后端开发,通过实现一个支持多线程并发下载与断点续传的文件下载器,深入探讨了网络编程、线程同步及文件I/O等工程实践。文中详细解析了HTTP Range请求

caodaoxi的专栏 300

【Linux网络编程】第二弹---Socket编程入门指南:从IP、端口号到传输层协议及编程接口全解析

理解源 IP 和目的 IP;认识端口号:端口号范围划分,理解 "端口号" 和 "进程 ID",理解源端口号和目的端口号,理解 socket;传输层的典型代表:认识 TCP 协议,认识 UDP 协议;网络字节序;socket 编程接口:socket 常见 API,sockaddr 结构~~~

小林熬夜学习编程的博客 4601

基于 C++ 手写 HTTP 服务器:从请求解析到响应构建全流程解析

本文介绍了常见应用层协议及其用途,重点解析了HTTP协议的工作原理。通过实现一个简易HTTP服务器,展示了HTTP请求/响应的报文结构(首行、报头、空行、正文)及处理流程。文章对比了GET和POST方法的区别:GET将参数拼接在URL中,POST则将参数放在请求正文。最后强调HTTP协议本质是遵循特定格式的字符串通信,通过实现服务器揭示了浏览器与服务器交互的底层机制。

2302_77620024的博客 5万+

使用PHP脚本下载远程文件

 使用PHP脚本下载文件 说明:纯属无聊,写着玩。使用PHP脚本来下载文件,无非是通过两种方式,一种是使用system、exec等即有的函数调用系统自带的下载工具,比如 wget 之类的来下载文件,还有一种是使用php本身利用Socket来下载文件,我选择第二种方式。使用Socket下载文件,首先如果是http协议的文件,必须明白HTTP协议的运行过程,如果是FTP协议的则要了解ftp协议运行

.NET博文收藏 550
上一篇: 一个linux典型的select模型更新方法
下一篇: Linux console
wolfzone025
博客等级 码龄16年 35粉丝 25原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值