C++ 简单实现HTTP GET/POST 请求

el/2024/6/13 12:18:59

HTTP(超文本传输协议)是一种客户端与服务端的传输协议,最早用于浏览器和服务器之间的通信,后来因为其使用灵活、方便等特点,广泛用于客户端与服务端的通信。文章将简单介绍HTTP协议,同时以C++方式分别实现HTTP GET、POST 请求

HTTP 请求报文

HTTP请求报文的一般格式由4部分组成:请求行、请求头部、空行、请求数据。如下图所示:

 

1.jpg

请求行:包含3部分内容:请求方法,URL,协议版本。形式如:GET /?aaa=1 HTTP/1.1。请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS等。URL指请求服务端的地址,可以是相对地址或域名形式的绝对地址。协议版本主要有HTTP/1.1 HTTP/1.0 HTTP/0.9,后面两种已很少使用了。

请求头部:以key/value形式成对表示头部参数,以英文冒号分隔。key名称的约定写法为Key,Key-Name,自定义key名称一般以“X-”开头。如php的声明“X-Powered-By:PHP/5.5.4-1”

空行:用来标识请求头部的数据已结束。

请求数据:可选项,这块内容只在POST方式下使用,作为POST的数据表示区域。使用这块内容,要在请求头部以Content-Length声明请求数据长度,以Content-Type声明请求数据类型。

HTTP POST请求

HTTP POST方式是把请求参数放到HTTP请求报文的请求数据中,为了让例子更容易看懂,仅保留HTTP Post关键参数,你还可以自定义一些参数,比如浏览器喜欢用的User-Agent,Accept,Connection等等

char *pHttpPost = "POST %s HTTP/1.1\r\n""Host: %s:%d\r\n""Content-Type: application/x-www-form-urlencoded\r\n""Content-Length: %d\r\n\r\n""%s";char* addr = "http://localhost/post.php";
char* host = "127.0.0.1";
int port = 80;
char* msg = "aaa=1&bbb=2";char strHttpPost[1024] = {0};
sprintf(strHttpPost, pHttpPost, addr, host, port, strlen(msg), msg);//这里忽略掉了socket连接代码send(sockClient, strHttpPost, strlen(strHttpPost), 0);

HTTP GET请求

HTTP GET方式是把请求参数放到HTTP请求报文的请求行URL中,所以请求行就是“GET /?aaa=1&bbb=2 HTTP/1.1\r\n”。URL最大长度通常浏览器取255,这和文件路径最大长度有关。虽然HTTP允许更大长度,但不建议怎么做,如果太长了,可以考虑换成POST方式

char *pHttpGet = "GET %s?%s HTTP/1.1\r\n""Host: %s:%d\r\n\r\n";char* addr = "http://localhost/get.php";
char* host = "127.0.0.1";
int post = 80;
char* msg = "aaa=1&bbb=2";char strHttpGet[1024] = {0};
sprintf(strHttpGet, pHttpGet, addr, msg,  host, post);//这里忽略掉了socket连接代码send(sockClient, strHttpGet, strlen(strHttpGet), 0);

实现的HTTP

#include "HttpConnect.h"#ifdef WIN32
#pragma comment(lib,"ws2_32.lib")
#endif
HttpConnect::HttpConnect()
{
#ifdef WIN32//此处一定要初始化一下,否则gethostbyname返回一直为空WSADATA wsa = { 0 };WSAStartup(MAKEWORD(2, 2), &wsa);
#endif
}
HttpConnect::~HttpConnect()
{
}
void HttpConnect::socketHttp(std::string host, std::string request)
{int sockfd;struct sockaddr_in address;struct hostent *server;sockfd = socket(AF_INET,SOCK_STREAM,0);address.sin_family = AF_INET;address.sin_port = htons(80);server = gethostbyname(host.c_str());memcpy((char *)&address.sin_addr.s_addr,(char*)server->h_addr, server->h_length);if(-1 == connect(sockfd,(struct sockaddr *)&address,sizeof(address))){DBG <<"connection error!"<<std::endl;return;}DBG << request << std::endl;
#ifdef WIN32send(sockfd, request.c_str(),request.size(),0);
#elsewrite(sockfd,request.c_str(),request.size());
#endifchar buf[1024*1024] = {0};int offset = 0;int rc;
#ifdef WIN32while(rc = recv(sockfd, buf+offset, 1024,0))
#elsewhile(rc = read(sockfd, buf+offset, 1024))
#endif{offset += rc;}
#ifdef WIN32closesocket(sockfd);
#elseclose(sockfd);
#endifbuf[offset] = 0;DBG << buf << std::endl;
}
void HttpConnect::postData(std::string host, std::string path, std::string post_content)
{//POST请求方式std::stringstream stream;stream << "POST " << path;stream << " HTTP/1.0\r\n";stream << "Host: "<< host << "\r\n";stream << "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n";stream << "Content-Type:application/x-www-form-urlencoded\r\n";stream << "Content-Length:" << post_content.length()<<"\r\n";stream << "Connection:close\r\n\r\n";stream << post_content.c_str();socketHttp(host, stream.str());
}
void HttpConnect::getData(std::string host, std::string path, std::string get_content)
{//GET请求方式std::stringstream stream;stream << "GET " << path << "?" << get_content;stream << " HTTP/1.0\r\n";stream << "Host: " << host << "\r\n";stream <<"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n";stream <<"Connection:close\r\n\r\n";socketHttp(host, stream.str());
}
    HttpConnect *http = new HttpConnect();http->getData("127.0.0.1", "/login", "id=liukang&pw=123");http->postData("127.0.0.1", "/login","id=liukang&pw=123");

 


http://www.ngui.cc/el/5545761.html

相关文章

C#无损高质量压缩图片实现代码

最近&#xff0c;项目上涉及到了图像压缩&#xff0c;发现原有的图像压缩功能&#xff0c;虽然保证了图像的大小300K以内&#xff0c;但是压缩后的图像看的不在清晰&#xff0c;并且&#xff0c;限定了图片的Height或者是Width。 在CSDN上看到了一个压缩算法&#xff1a;C#无损…

vs中c++项目的配置

首先&#xff0c;我们一般不会修改解决方案的属性&#xff0c;而是设置每个项目各自的属性. 接着上一篇文章&#xff0c;我们来看看我们应该怎样来设置各项目的项目属性更好&#xff1a; 我们以NYOJ_001项目的Debug版的设置为例&#xff1a; 在常规选项里&#xff0c;我们一…

关于opencv中Mat赋值(浅拷贝,深拷贝)原理

问题点&#xff1a; 有两个垫对象&#xff1a;mat_1和mat_2将mat_2赋值给mat_1&#xff08;mat_1 mat_2&#xff09;后&#xff0c;改变mat_1&#xff0c;mat_2也会被改变&#xff08;这里的改变是指图像处理&#xff09;。 原因&#xff1a; mat_1 mat_2是浅拷贝&#xff0…

c#中获取控件窗体句柄,获取窗体等的一些操作

1.Control.Handle 就是获取控件绑定到的窗口句柄。 2.control.IsHandleCreated 控件是否有与其关联的句柄 3.WinForm自定义函数FindControl实现按名称查找控件 public static Control FindControl(Control parentControl, string findCtrlName) { Control _findedCon…

c#滚动条创建实例,多线程

1.滚动条 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApplicati…

用最小二乘法拟合任意次函数曲线(C#)

///<summary> ///用最小二乘法拟合二元多次曲线 ///</summary> ///<param name"arrX">已知点的x坐标集合</param> ///<param name"arrY">已知点的y坐标集合</param> ///<param name"length&qu…

C#操作快捷方式(获取快捷方式属性、创建快捷方式)

第一步 创建一个项目 无需废话&#xff0c;跳过。 第二步 引用COM组件 右键“引用”&#xff0c;“添加引用”&#xff0c;选择“COM组件”&#xff0c;找到“Windows Script Host Object Model”&#xff0c;然后确定。 第三步 编写创建快捷方式的代码 1 // 声明操作对…

让使用SQLite的.NET应用自适应32位/64位系统

Windows 7 64 bit(刚扩到4G内存,果断换64位的,那速度杠杠的) Microsoft Visual Studio 2010 Ultimate 32bit(在64位系统里运行正常) sqlite-netFx40-setup-bundle-x64-2010-1.0.90.0 首先要先下载SQLite的开发环境安装包(我是这么理解的,貌似只搞到System.Data.SQLite.dll这个文…

C#使用DataContractJsonSerializer来进行JSON解析

在使用DataContractJsonSerializer进行解析之前&#xff0c;我们首先需要将两个包引入进来&#xff1a; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; 接下来需要新建一个class&#xff0c;DataContractJsonSerializer可以将JSON字符串转化…

QT操作sqlite概念

SQLite数据库 增、删、改、查 1. 数据库简介 数据库指的是以一定方式存储在一起&#xff0c;能为多个用户共享&#xff0c;具有尽可能小的冗余度的特点&#xff0c;是与应用程序彼此独立的数据集合。 // 一定方式&#xff1a;可以理解为策略、算法 // 网盘相同的文件是以 MD…