跨平台c++/boost/asio 简单的HTTP POST请求 客户端模型
作为一个呼应,写一个c++版本的同步http post客户端功能,如果你需要纯C版本,移步这里
讲解一下基本的的http post协议
- 通过\r\n,实现tcp的消息边界
- 每个请求的第一段 POST /a.b HTTP/1.1
- POST http的方法,还有最常用的GET,当然还有其他的几种,略过
- /a.b 请求的网页路径,比如如果是首页,最经常的就是/
- HTTP/1.1 http协议的版本号,传说中已经出了2了,还有神奇的谷歌出的用来替代http协议的SPDY
- 通过这条信息表明这是一个表单
- Content-Type: application/x-www-form-urlencoded
- 通过这条信息来表示这次httppost 的包体长度,非必需项
- Content-Length:12
- 然后就是一个空行,代表接下来都是包体
刚才是请求,谈一下响应就更简单了
- 响应内容 HTTP/1.1 200 OK
- 200就是传送中的状态,404没找喔等等
- HTTP/1.1 表示http的版本号
- 当然,如果包头也是可以存在,此处不介绍
- 然后就是一个空行,分割是包体
好了,直接上代码吧
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp> using boost::asio::ip::tcp;
using std::string; int post(const string& host, const string& port, const string& page, const string& data, string& reponse_data)
{
try
{
boost::asio::io_service io_service;
//如果io_service存在复用的情况
if(io_service.stopped())
io_service.reset(); // 从dns取得域名下的所有ip
tcp::resolver resolver(io_service);
tcp::resolver::query query(host, port);
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); // 尝试连接到其中的某个ip直到成功
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator); // Form the request. We specify the "Connection: close" header so that the
// server will close the socket after transmitting the response. This will
// allow us to treat all data up until the EOF as the content.
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "POST " << page << " HTTP/1.0\r\n";
request_stream << "Host: " << host << ":" << port << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Content-Length: " << data.length() << "\r\n";
request_stream << "Content-Type: application/x-www-form-urlencoded\r\n";
request_stream << "Connection: close\r\n\r\n";
request_stream << data; // Send the request.
boost::asio::write(socket, request); // Read the response status line. The response streambuf will automatically
// grow to accommodate the entire line. The growth may be limited by passing
// a maximum size to the streambuf constructor.
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n"); // Check that response is OK.
std::istream response_stream(&response);
std::string http_version;
response_stream >> http_version;
unsigned int status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (!response_stream || http_version.substr(, ) != "HTTP/")
{
reponse_data = "Invalid response";
return -;
}
// 如果服务器返回非200都认为有错,不支持301/302等跳转
if (status_code != )
{
reponse_data = "Response returned with status code != 200 " ;
return status_code;
} // 传说中的包头可以读下来了
std::string header;
std::vector<string> headers;
while (std::getline(response_stream, header) && header != "\r")
headers.push_back(header); // 读取所有剩下的数据作为包体
boost::system::error_code error;
while (boost::asio::read(socket, response,
boost::asio::transfer_at_least(), error))
{
} //响应有数据
if (response.size())
{
std::istream response_stream(&response);
std::istreambuf_iterator<char> eos;
reponse_data = string(std::istreambuf_iterator<char>(response_stream), eos);
} if (error != boost::asio::error::eof)
{
reponse_data = error.message();
return -;
}
}
catch(std::exception& e)
{
reponse_data = e.what();
return -;
}
return ;
} int main(int argc, char* argv[])
{
string host = "127.0.0.1";
string port = "";
string page = "/auth/login";
string data = "user_name=linbc&password=a";
string reponse_data; int ret = post(host, port, page, data, reponse_data);
if (ret != )
std::cout << "error_code:" << ret << std::endl; std::cout << reponse_data << std::endl; return ;
}
编译一下吧。。
g++ post.cc -std=c++11 -pthread -lboost_system
跨平台c++/boost/asio 简单的HTTP POST请求 客户端模型的更多相关文章
- 使用 boost.asio 简单实现 异步Socket 通信
客户端: class IPCClient { public: IPCClient(); ~IPCClient(); bool run(); private: bool connect(); bool ...
- boost asio异步读写网络聊天程序客户端 实例详解
boost官方文档中聊天程序实例讲解 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...
- 使用boost.asio实现网络通讯
#include <boost/asio.hpp> #define USING_SSL //是否加密 #ifdef USING_SSL #include <boost/asio/ss ...
- boost::asio译文
Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENS ...
- Boost.Asio技术文档
Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_ ...
- #include <boost/asio.hpp>
TCP服务端和客户端 TCP服务端 #include <iostream> #include <stdlib.h> #include <boost/asio.hpp> ...
- (原创)如何使用boost.asio写一个简单的通信程序(一)
boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...
- (原创)如何使用boost.asio写一个简单的通信程序(二)
先说下上一篇文章中提到的保持io_service::run不退出的简单办法.因为只要异步事件队列中有事件,io_service::run就会一直阻塞不退出,所以只要保证异步事件队列中一直有事件就行了, ...
- boost::asio之(一)简单客户端服务器回显功能
客户端: // BoostDev.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #inc ...
随机推荐
- 【Lua】Lua + openresty遍历文件目录
OpenResty (也称为 ngx_openresty)是一个全功能的 Web 应用服务器,它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项. 今天用OpenRest ...
- VirtualBox 虚拟机磁盘空间不够用,增大空间方法(这里以MAC为例)
开始在Virtualbox 上,安装MAC系统的时候只分配了20G的空间,随着Xcode 开发软件安装的东西多了,比如:IOS 的Simulator 的各种版本,4.3,5.0,6.0 加起来要到少要 ...
- Game-Tech小游戏专场第二趴,这次帝都见
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯游戏云 发表于云+社区专栏 自从小游戏推出以来,凭借微信带来的巨大流量和变现能力,小游戏生态极速地建立了起来,短短半年多时间已经出 ...
- [转]真正了解CSS3背景下的@font face规则
本文转自:http://www.zhangxinxu.com/wordpress/2017/03/css3-font-face-src-local/ by zhangxinxu from http:/ ...
- Shiro - 与Spring集成
本文是针对web应用web.xml: <filter> <filter-name>shiroFilter</filter-name> <filter-clas ...
- Oracle数据库查看已添加的索引和创建索引
/** *查看目标表中已添加的索引 * */ --在数据库中查找表名 select * from user_tables where table_name like 'tablename%'; --查 ...
- 七、cent OS下干净卸载mysql
使用以下命令查看当前安装mysql的情况rpm -qa | grep -i mysql显示之前安装的东西,示例:MySQL-client-5.5.25a-1.rhel5MySQL-server-5.5 ...
- docker 数据卷挂载总结
原文
- Spring课程 Spring入门篇 6-3 ProxyFactoryBean及相关内容(下)
1 解析 1.1 使用global advisors demo 1.2 jdk代理和cglib代理的选择 1.3 如何强制使用CGLIB实现AOP? 1.4 JDK动态代理和CGLIB字节码生成的区别 ...
- CakePHP redirect函数
public function getContract($value=''){ App::uses ( 'UserContractController', 'Controller' ); $Contr ...