作为一个呼应,写一个c++版本的同步http post客户端功能,如果你需要纯C版本,移步这里

linux下纯C简单的HTTP POST请求 客户端模型

讲解一下基本的的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请求 客户端模型的更多相关文章

  1. 使用 boost.asio 简单实现 异步Socket 通信

     客户端: class IPCClient { public: IPCClient(); ~IPCClient(); bool run(); private: bool connect(); bool ...

  2. boost asio异步读写网络聊天程序客户端 实例详解

    boost官方文档中聊天程序实例讲解 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...

  3. 使用boost.asio实现网络通讯

    #include <boost/asio.hpp> #define USING_SSL //是否加密 #ifdef USING_SSL #include <boost/asio/ss ...

  4. boost::asio译文

        Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENS ...

  5. Boost.Asio技术文档

    Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_ ...

  6. #include <boost/asio.hpp>

    TCP服务端和客户端 TCP服务端 #include <iostream> #include <stdlib.h> #include <boost/asio.hpp> ...

  7. (原创)如何使用boost.asio写一个简单的通信程序(一)

    boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...

  8. (原创)如何使用boost.asio写一个简单的通信程序(二)

    先说下上一篇文章中提到的保持io_service::run不退出的简单办法.因为只要异步事件队列中有事件,io_service::run就会一直阻塞不退出,所以只要保证异步事件队列中一直有事件就行了, ...

  9. boost::asio之(一)简单客户端服务器回显功能

    客户端: // BoostDev.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #inc ...

随机推荐

  1. Java学习之路(二):Java中的方法

    Java中的方法 概念: 为什么要有方法: 提高代码的复用性 什么是方法: 完成特定功能的代码块 格式: 修饰符 返回值类型 方法名(参数){ 方法体语句: return 返回值: } 1.修饰符:例 ...

  2. Python基础(3) - 数据类型:3列表类型

    Python 列表是序列对象,可包含任意的Python数据信息,如字符串.数字.列表.元组等.列表的数据是可变的,我们可通过对象方法对列表中的数据进行增加.修改.删除等操作.列表用[]包括起来的. 列 ...

  3. Centos7 ftp服务器搭建

    1.使用yum安装ftp服务端: yum install -y vsftpd 2.使用yum安装ftp客户端: yum install -y ftp.x86_64 3.开启ftp服务设置开机启动并查看 ...

  4. 架构实战项目心得(六)(补):mongodb.conf参数详解

    --dbpath 数据库路径(数据文件)--logpath 日志文件路径--master 指定为主机器--slave 指定为从机器--source 指定主机器的IP地址--pologSize 指定日志 ...

  5. 《Maven实战》关联实际工作的核心知识

    通读了<Maven实战>这本书,由于在实际的工作中,对其有一定的操作上的经验.因此,再回头去通读这本书,就能够更加精准的把握里面的核心知识了. 以下我主要从两点去介绍之—— 1> m ...

  6. easyui表单校验拓展

    /** * Created by chaozhou on 2016/5/30. */ /** * 扩展的基本校验规则, */ $.extend($.fn.validatebox.defaults.ru ...

  7. nodejs时间工具类

    /** * * @fmt 格式化字符串 * @Date 为需要格式化的日期 * * 示例:format(new Date(),'yyyy-MM-dd hh:mm:ss'); * 返回值为字符串 */ ...

  8. Kettle系列文章二(安装配置Kettle+SqlServer+简单的输入输出作业)

    一.下载 Kettle下载地址:https://community.hitachivantara.com/docs/DOC-1009855 下拉到DownLoad,点击红框中的链接进行下载.. 二.解 ...

  9. three.js 在vscode的智能提示

    安装nodejs.启动或者重启vscode,打开控制台,输入命令 npm install --save @types/three 回车, 会多了个node_modules文件夹,再试试智能感知,出来. ...

  10. 如何去除vue项目中的 # — vue路由的History模式

    前言 在创建的 router 对象中,如果不配置 mode,就会使用默认的 hash 模式,该模式下会将路径格式化为 #! 开头. 添加 mode: 'history' 之后将使用 HTML5 his ...