Http请求通过线程添加超时处理
来源:互联网 发布:工程量预算软件 编辑:程序博客网 时间:2024/06/07 10:51
解决问题:
1.通过boost库asio去发送Http post请求,本文采用官方的同步调用方式(http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/http/client/sync_client.cpp)
2.因为socket读写可能会堵塞,如Server迟迟没有返回,此时需要设置timeout来中断本次处理,
因而采用新建线程HttpClient::wait_timeout来解决此问题,
3.LOGGER_DEBUG输出请自行修改
4.调用方式如下:
std::string ip ="172.16.17.58";
std::string port = "8181";
std::string path = "/login/";
std::string http_req_body = "user_name=tx02&password=e10adc3949ba59abbe56e057f20f8888";
HttpClient client(ip, port, path, http_req_body);
if(0 == client.post())
{
std::string response = client.getResponse()
......
}
代码如下:
1. HttpClient.h
#ifndef _HTTPCLIENT_H_#define _HTTPCLIENT_H_#include <string>#include "logger.h"#include <boost/asio.hpp>#include "boost/thread/mutex.hpp"#include "boost/thread/condition_variable.hpp"using boost::asio::ip::tcp;class HttpClient{public:HttpClient(const std::string&ip, const std::string&port);HttpClient(const std::string&ip, const std::string&port, const std::string&path,const std::string&content);~HttpClient(void);public:std::string setUrl(const std::string& path){path_ = path;};std::string setContent(const std::string& content){content_ = content;};std::string getResponse(){return body_;};int post();private:std::string getValidJson(const std::string& response);void wait_timeout(tcp::socket *socket);void incrementAliveThread();void decrementAliveThread();void interruptThread();private:std::string ip_;std::string port_;std::string path_;std::string content_;std::string body_;boost::mutex mu_; boost::condition_variable_any cond_; int alive_thread_count;};#endif // _HTTPCLIENT_H_2. HttpClient.cpp
#include "httpclient.h"#include <iostream>#include <istream>#include <ostream>#include <string>#include <boost/property_tree/ptree.hpp>#include <boost/property_tree/json_parser.hpp>#include <boost/thread.hpp> #include <boost/bind.hpp>#include <boost/function/function0.hpp>HttpClient::HttpClient(const std::string&ip, const std::string&port):ip_(ip),port_(port){alive_thread_count = 0;}HttpClient::HttpClient(const std::string&ip, const std::string&port, const std::string&path,const std::string&content):ip_(ip),port_(port),path_(path),content_(content){alive_thread_count = 0;}HttpClient::~HttpClient(void){}void HttpClient::incrementAliveThread(){boost::mutex::scoped_lock lock(mu_); alive_thread_count++;LOGGER_DEBUG("incrementAliveThread " << alive_thread_count);}void HttpClient::decrementAliveThread(){boost::mutex::scoped_lock lock(mu_); alive_thread_count--;LOGGER_DEBUG("decrementAliveThread " << alive_thread_count);}void HttpClient::interruptThread(){while(alive_thread_count){LOGGER_DEBUG("Force the thread finish");boost::mutex::scoped_lock lock(mu_); cond_.notify_all(); boost::this_thread::sleep(boost::posix_time::milliseconds(5)); }}void HttpClient::wait_timeout(tcp::socket *socket) { {boost::mutex::scoped_lock lock(mu_); if (cond_.timed_wait(lock, boost::get_system_time() + boost::posix_time::seconds(10))) { LOGGER_DEBUG("recieved notification!"); } else { LOGGER_ERROR("timeout, didn't recieve notification!"); socket->close();}}decrementAliveThread();}int HttpClient::post(){try{int ret = 0;alive_thread_count = 0;// Get a list of endpoints corresponding to the server name.boost::asio::io_service io_service;tcp::resolver resolver(io_service);tcp::resolver::query query(ip_, port_);tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);// Try each endpoint until we successfully establish a connection.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 " << path_ << " HTTP/1.1\r\n";request_stream << "Host: " << ip_ << "\r\n";request_stream << "Accept: */*\r\n";request_stream << "Connection: close\r\n";request_stream << "Content-Type: application/json; charset=utf-8 \r\n";request_stream << "Content-Length: " << content_.length() << "\r\n";request_stream << "\r\n";request_stream << content_;// Send the request.boost::function0<void> f = boost::bind(&HttpClient::wait_timeout,this, &socket); incrementAliveThread(); boost::thread t(f); 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(0, 5) != "HTTP/"){interruptThread();LOGGER_ERROR("Invalid response" );return 1;}if (status_code != 200){interruptThread();LOGGER_ERROR("Response returned with status code " << status_code);return 2;}// Read the response headers, which are terminated by a blank line.boost::asio::read_until(socket, response, "\r\n\r\n");// Process the response headers.std::string header;while (std::getline(response_stream, header) && header != "\r"){LOGGER_DEBUG(header);}// Write whatever content we already have to output.std::ostringstream ss;if (response.size() > 0){ss << &response;body_ = ss.str();}// Read until EOF, writing data to output as we go.boost::system::error_code error;while (boost::asio::read(socket, response,boost::asio::transfer_at_least(1), error)){ss << &response;body_ += ss.str();}{boost::mutex::scoped_lock lock(mu_); cond_.notify_all();}LOGGER_DEBUG("response body: " << body_);
if (error != boost::asio::error::eof)throw boost::system::system_error(error);}catch (std::exception& e){interruptThread();LOGGER_ERROR("Exception: " << e.what());return 3;}interruptThread();LOGGER_INFO("post request succeed");return 0;}
参考:
0 0
- Http请求通过线程添加超时处理
- HTTp 请求json 超时
- ajax请求超时处理
- web 会话超时,请求(http请求和ajax异步请求)处理
- web 会话超时,请求(http请求和ajax异步请求)处理
- 安卓中处理http超时
- 线程超时处理Demo
- JAVA处理线程超时
- JAVA处理线程超时
- JAVA处理线程超时
- java线程超时处理
- 线程超时处理
- JAVA处理线程超时
- JAVA处理线程超时
- http 请求 超时时间设置
- Nodejs HTTP请求的超时处理 Nodejs HTTP Client Request Timeout Handle
- 探究django能否通过线程返回http请求
- session超时,处理ajax请求
- Android 实现ListView的A-Z字母排序和过滤搜索功能,实现汉字转成拼音
- 关于lingo的例子
- Java学习之路0813(HttpClient中的doGet和doPost实例)
- Android之Service启动方式
- HDU 3507 Print Article
- Http请求通过线程添加超时处理
- SDL源码阅读笔记(1) 基本模块
- maven3常用命令
- 马士兵视频中的生产者与消费者的经典问题
- hibernate对应的bean。表里是int型的数据,bean要用Integer类型。
- IDEA下使用Jetty进行Debug模式调试
- robotframework+selenium2Library使用遇到的问题
- 原生JavaScript addClass() removeClass()
- 关于调试GPS45711的记录