微信小程序lianc++后台

2017-01-10


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

[javascript] view plain copy

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  

[javascript] view plain copy

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:

[cpp] view plain copy

//  

// 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、

[cpp] view plain copy

//  

// 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;  

}  

[cpp] view plain copy

bool request_parser::is_tspecial(int c)  

[cpp] view plain copy

{  

  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类增加了自己处理客户端请求函数,不用官方的


[cpp] view plain copy

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函数增加自己处理客户的请求函数

[cpp] view plain copy

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类增加了自己处理客户端请求函数,不用官方的


[cpp] view plain copy

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;  

    }  

    }  

}  




0
收藏