跨平台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 ...
随机推荐
- Zookeeper概念学习系列之分布式事务
不多说,直接上干货! 初学者来说,肯定会有这么一个疑问.为什么会在zookeeper里牵扯到分布式事务? zookeeper到底是什么? zookeeper实际上是yahoo开发的,用于分布式中一致性 ...
- tomcat端口冲突解决 Address already in use: JVM_Bind <null>:8080
java.net.BindException: Address already in use: JVM_Bind <null>:8080 Caused by: java.net.BindE ...
- Python生成pyc文件
Python生成pyc文件 pyc文件是py文件编译后生成的字节码文件(byte code).pyc文件经过python解释器最终会生成机器码运行.所以pyc文件是可以跨平台部署的,类似Java的.c ...
- python风味之list创建
单重for循环 >>> [x * x for x in xrange(10)] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 单重for循环+if条件 & ...
- Linux中常用头文件的作用--转
http://blog.sina.com.cn/s/blog_5c93b2ab0100q62k.html 1. Linux中一些头文件的作用: <assert.h>:ANSI C.提供断言 ...
- 周记4——vue中动态添加图片无效、build上线后background-image路径问题
又是一个周五,又一周要过去了...很开心,这周遇到了vue中的一个比较常见的坑,网上随便一搜就有了很多解决方案...“幸运”的是,我选了一个带坑的方案...所以我觉得有必要记录一下这个“坑中坑”... ...
- [SpringBoot系列]--Spring Hibernate search 注解实现(未测试)
1.maven项目pom.xml加入依赖 <dependency> <groupId>org.hibernate</groupId> <artifactId& ...
- awk中引用变量使用单引号''
举例如下 who命令输出第一列 (1)第一种情况不使用引号 # i=1;who | awk '{print $${i}}' 输出如下: awk: {print $${i}} awk: ...
- java 并发(五)---AbstractQueuedSynchronizer(2)
文章部分代码和照片来自参考资料 问题 : ConditionObject 的 await 和 signal 方法是如何实现的 ConditonObject ConditionObjec ...
- Nginx配置整理
不论是本地开发,还是远程到 Server 开发,还是给提供 demo 给人看效果,我们时常需要对 Nginx 做配置,Nginx 的配置项相当多,如果考虑性能配置起来会比较麻烦.不过,我们往往只是需要 ...