微信小程序lianc++后台

贴上微信小程序发送http请求代码:

 onsend: function(){    
    wx.request({
       url: 'http://127.0.0.1:1000', //c++后台ip、端口
       data: {
           x: '1' , //发送到后台字段
           y: '2'
  },
  header:{
      "Content-Type":"application/json"
  },
  method:"POST", //发送POST,若为GET则改为GET
  success: function(res) {
     var data = res.data;
     console.log(data);
  }
  });
  }

c++后台代码借鉴boost官网的asio的http server 3地址并自己做了修改:

官网地址:http://www.boost.org/doc/libs/1_38_0/doc/html/boost_asio/examples.html

修改代码:

1、request_parser.hpp:

//
// request_parser.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef HTTP_SERVER3_REQUEST_PARSER_HPP
#define HTTP_SERVER3_REQUEST_PARSER_HPP

#include <boost/logic/tribool.hpp>
#include <boost/tuple/tuple.hpp>

namespace http {
namespace server3 {

struct request;

/// Parser for incoming requests.
class request_parser
{
public:
  /// Construct ready to parse the request method.
  request_parser();

  /// Reset to initial parser state.
  void reset();

  /// Parse some data. The tribool return value is true when a complete request
  /// has been parsed, false if the data is invalid, indeterminate when more
  /// data is required. The InputIterator return value indicates how much of the
  /// input has been consumed.
  template <typename InputIterator>
  boost::tuple<boost::tribool, InputIterator> parse(request& req,
      InputIterator begin, InputIterator end)
  {
    if(req.method=="POST") state_ = expecting_newline_4; //自己增加针对post请求数据一次性接收不完问题
    while (begin != end)
    {
      boost::tribool result = consume(req, *begin++);
	  
	  if (state_ != none && (result || !result)){ //针对post请求做特殊处理

		   if(req.method=="POST"){
			   char c = *begin;
			   if(c=='\0') break;
			 state_ = expecting_newline_4;
		     result = consume(req, *begin++);
	       }  
		 
	  }
      if (result || !result){
		    return boost::make_tuple(result, begin);
	   }
    }
    boost::tribool result = boost::indeterminate;
    return boost::make_tuple(result, begin);
  }

private:
  /// Handle the next character of input.
  boost::tribool consume(request& req, char input);

  /// Check if a byte is an HTTP character.
  static bool is_char(int c);

  /// Check if a byte is an HTTP control character.
  static bool is_ctl(int c);

  /// Check if a byte is defined as an HTTP tspecial character.
  static bool is_tspecial(int c);

  /// Check if a byte is a digit.
  static bool is_digit(int c);

  /// The current state of the parser.
  enum state
  {
    method_start,
    method,
    uri_start,
    uri,
    http_version_h,
    http_version_t_1,
    http_version_t_2,
    http_version_p,
    http_version_slash,
    http_version_major_start,
    http_version_major,
    http_version_minor_start,
    http_version_minor,
    expecting_newline_1,
    header_line_start,
    header_lws,
    header_name,
    space_before_header_value,
    header_value,
    expecting_newline_2,
    expecting_newline_3,
    expecting_newline_4,//针对post请求
    none //针对post请求
  } state_;
};

} // namespace server3
} // namespace http

#endif // HTTP_SERVER3_REQUEST_PARSER_HPP

2、
//
// request_parser.cpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include "request_parser.hpp"
#include "request.hpp"

namespace http {
namespace server3 {

request_parser::request_parser()
  : state_(method_start)
{
}

void request_parser::reset()
{
  state_ = method_start;
}

boost::tribool request_parser::consume(request& req, char input)
{
  switch (state_)
  {
  case method_start:
    if (!is_char(input) || is_ctl(input) || is_tspecial(input))
    {
      return false;
    }
    else
    {
      state_ = method;
      req.method.push_back(input);
      return boost::indeterminate;
    }
  case method:
    if (input == ' ')
    {
      state_ = uri;
      return boost::indeterminate;
    }
    else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
    {
      return false;
    }
    else
    {
      req.method.push_back(input);
      return boost::indeterminate;
    }
  case uri_start:
    if (is_ctl(input))
    {
      return false;
    }
    else
    {
      state_ = uri;
      req.uri.push_back(input);
      return boost::indeterminate;
    }
  case uri:
    if (input == ' ')
    {
      state_ = http_version_h;
      return boost::indeterminate;
    }
    else if (is_ctl(input))
    {
      return false;
    }
    else
    {
      req.uri.push_back(input);
      return boost::indeterminate;
    }
  case http_version_h:
    if (input == 'H')
    {
      state_ = http_version_t_1;
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case http_version_t_1:
    if (input == 'T')
    {
      state_ = http_version_t_2;
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case http_version_t_2:
    if (input == 'T')
    {
      state_ = http_version_p;
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case http_version_p:
    if (input == 'P')
    {
      state_ = http_version_slash;
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case http_version_slash:
    if (input == '/')
    {
      req.http_version_major = 0;
      req.http_version_minor = 0;
      state_ = http_version_major_start;
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case http_version_major_start:
    if (is_digit(input))
    {
      req.http_version_major = req.http_version_major * 10 + input - '0';
      state_ = http_version_major;
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case http_version_major:
    if (input == '.')
    {
      state_ = http_version_minor_start;
      return boost::indeterminate;
    }
    else if (is_digit(input))
    {
      req.http_version_major = req.http_version_major * 10 + input - '0';
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case http_version_minor_start:
    if (is_digit(input))
    {
      req.http_version_minor = req.http_version_minor * 10 + input - '0';
      state_ = http_version_minor;
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case http_version_minor:
    if (input == '\r')
    {
      state_ = expecting_newline_1;
      return boost::indeterminate;
    }
    else if (is_digit(input))
    {
      req.http_version_minor = req.http_version_minor * 10 + input - '0';
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case expecting_newline_1:
    if (input == '\n')
    {
      state_ = header_line_start;
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case header_line_start:
    if (input == '\r')
    {
      state_ = expecting_newline_3;
      return boost::indeterminate;
    }
    else if (!req.headers.empty() && (input == ' ' || input == '\t'))
    {
      state_ = header_lws;
      return boost::indeterminate;
    }
    else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
    {
      return false;
    }
    else
    {
      req.headers.push_back(header());
      req.headers.back().name.push_back(input);
      state_ = header_name;
      return boost::indeterminate;
    }
  case header_lws:
    if (input == '\r')
    {
      state_ = expecting_newline_2;
      return boost::indeterminate;
    }
    else if (input == ' ' || input == '\t')
    {
      return boost::indeterminate;
    }
    else if (is_ctl(input))
    {
      return false;
    }
    else
    {
      state_ = header_value;
      req.headers.back().value.push_back(input);
      return boost::indeterminate;
    }
  case header_name:
    if (input == ':')
    {
      state_ = space_before_header_value;
      return boost::indeterminate;
    }
    else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
    {
      return false;
    }
    else
    {
      req.headers.back().name.push_back(input);
      return boost::indeterminate;
    }
  case space_before_header_value:
    if (input == ' ')
    {
      state_ = header_value;
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case header_value:
    if (input == '\r')
    {
      state_ = expecting_newline_2;
      return boost::indeterminate;
    }
    else if (is_ctl(input))
    {
      return false;
    }
    else
    {
      req.headers.back().value.push_back(input);
      return boost::indeterminate;
    }
  case expecting_newline_2:
    if (input == '\n')
    {
      state_ = header_line_start;
      return boost::indeterminate;
    }
    else
    {
      return false;
    }
  case expecting_newline_3:
    return (input == '\n');
  case expecting_newline_4: //针对post请求做处理
	  {
		req.post.push_back(input);
		if(input=='}') {
			state_ = none; //对post请求处理完成。
			return true;
		}
	    return boost::indeterminate;
	  }
  default:
    return false;
  }
}

bool request_parser::is_char(int c)
{
  return c >= 0 && c <= 127;
}

bool request_parser::is_ctl(int c)
{
  return c >= 0 && c <= 31 || c == 127;
}
bool request_parser::is_tspecial(int c)
{
  switch (c)
  {
  case '(': case ')': case '<': case '>': case '@':
  case ',': case ';': case ':': case '\\': case '"':
  case '/': case '[': case ']': case '?': case '=':
  case '{': case '}': case ' ': case '\t':
    return true;
  default:
    return false;
  }
}

bool request_parser::is_digit(int c)
{
  return c >= '0' && c <= '9';
}

} // namespace server3
} // namespace http
3、



3、针对request_handler类增加了自己处理客户端请求函数,不用官方的

void request_handler::handle_request(const request& req)
{
	if(req.method=="POST"){
	 //json解析
		Json::Reader reader;
	Json::Value jsonval;
	if(!(reader.parse(req.post,jsonval)))
	{
		std::cerr << "json解析错误:" << req.post << std::endl;
		return ;
	}
	std::string funcid = jsonval["x"].asString();
	std::string content = jsonval["y"].asString();
	std::cout << "收到客户端请求:" <<req.post<< std::endl;
	}else{
    std::cout << "收到客户端请求:" <<req.uri.substr(2,req.uri.length())<< std::endl;
  	std::string str = req.uri;
	std::vector<std::string> vecSegTag;
	boost::split(vecSegTag, str, boost::is_any_of(("/?&=")));
	m_MapContent.clear();
	for(int i = 2; i < vecSegTag.size() - 1; ){
	   m_MapContent.insert(std::pair<std::string, std::string>(vecSegTag[i], vecSegTag[i+1]));
	   i += 2;
	}
	}
}

4、connection类修改handle_read函数增加自己处理客户的请求函数

void connection::handle_read(const boost::system::error_code& e,
    std::size_t bytes_transferred)
{
  if (!e)
  {	  
    boost::tribool result;
    boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
        request_, buffer_.data(), buffer_.data() + bytes_transferred);
	
	buffer_.assign('\0');
    if (result)
    {
		request_handler_.handle_request(request_);
		//std::map<std::string,std::string> tmp = request_handler_.getRequestContent();
    /*  request_handler_.handle_request(request_, reply_);*/
		 // Fill out the reply to be sent to the client.
  reply_.status = reply::ok;
  char buf[512] = {"hello"}; //回应客户端数据
 
    reply_.content.append(buf);
  reply_.headers.resize(2);
  reply_.headers[0].name = "Content-Length";
  reply_.headers[0].value = boost::lexical_cast<std::string>(reply_.content.size());
  reply_.headers[1].name = "Content-Type";
  reply_.headers[1].value = mime_types::extension_to_type("");

      boost::asio::async_write(socket_, reply_.to_buffers(),
          strand_.wrap(
            boost::bind(&connection::handle_write, shared_from_this(),
              boost::asio::placeholders::error)));
    }
    else if (!result)
    {
      reply_ = reply::stock_reply(reply::bad_request);
      boost::asio::async_write(socket_, reply_.to_buffers(),
          strand_.wrap(
            boost::bind(&connection::handle_write, shared_from_this(),
              boost::asio::placeholders::error)));
    }
    else
    {
      socket_.async_read_some(boost::asio::buffer(buffer_),
          strand_.wrap(
            boost::bind(&connection::handle_read, shared_from_this(),
              boost::asio::placeholders::error,
              boost::asio::placeholders::bytes_transferred)));
    }
  }

  // If an error occurs then no new asynchronous operations are started. This
  // means that all shared_ptr references to the connection object will
  // disappear and the object will be destroyed automatically after this
  // handler returns. The connection class's destructor closes the socket.
}


3、针对request_handler类增加了自己处理客户端请求函数,不用官方的

void request_handler::handle_request(const request& req)
{
	if(req.method=="POST"){
	 //json解析
		Json::Reader reader;
	Json::Value jsonval;
	if(!(reader.parse(req.post,jsonval)))
	{
		std::cerr << "json解析错误:" << req.post << std::endl;
		return ;
	}
	std::string funcid = jsonval["x"].asString();
	std::string content = jsonval["y"].asString();
	std::cout << "收到客户端请求:" <<req.post<< std::endl;
	}else{
    std::cout << "收到客户端请求:" <<req.uri.substr(2,req.uri.length())<< std::endl;
  	std::string str = req.uri;
	std::vector<std::string> vecSegTag;
	boost::split(vecSegTag, str, boost::is_any_of(("/?&=")));
	m_MapContent.clear();
	for(int i = 2; i < vecSegTag.size() - 1; ){
	   m_MapContent.insert(std::pair<std::string, std::string>(vecSegTag[i], vecSegTag[i+1]));
	   i += 2;
	}
	}
}

猜你喜欢

转载自blog.csdn.net/abqchina/article/details/53673101
今日推荐