说明
封装成一个完整的C++类,对于异常的校验和处理有待在实际的过程中,进一步加强,
目前对于套接字的关闭,释放网络资源应该是没有问题的
#include <iostream>
#include <fstream>
#include <string>
#include <boost/asio.hpp>
using namespace std;
using namespace boost::asio;
class CHttpPost;
unsigned char ToHex(unsigned char x)
{
return x > 9 ? x + 55 : x + 48;
}
unsigned char FromHex(unsigned char x)
{
unsigned char y;
if (x >= ‘A‘ && x <= ‘Z‘) y = x - ‘A‘ + 10;
else if (x >= ‘a‘ && x <= ‘z‘) y = x - ‘a‘ + 10;
else if (x >= ‘0‘ && x <= ‘9‘) y = x - ‘0‘;
else assert(0);
return y;
}
std::string UrlEncode(const std::string& str)
{
std::string strTemp = "";
size_t length = str.length();
for (size_t i = 0; i < length; i++)
{
if (isalnum((unsigned char)str[i]) ||
(str[i] == ‘-‘) ||
(str[i] == ‘_‘) ||
(str[i] == ‘.‘) ||
(str[i] == ‘~‘) ||
(str[i] == ‘&‘) ||
(str[i] == ‘=‘))
strTemp += str[i];
else if (str[i] == ‘ ‘)
strTemp += "+";
else
{
strTemp += ‘%‘;
strTemp += ToHex((unsigned char)str[i] >> 4);
strTemp += ToHex((unsigned char)str[i] % 16);
}
}
return strTemp;
}
std::string UrlDecode(const std::string& str)
{
std::string strTemp = "";
size_t length = str.length();
for (size_t i = 0; i < length; i++)
{
if (str[i] == ‘+‘) strTemp += ‘ ‘;
else if (str[i] == ‘%‘)
{
assert(i + 2 < length);
unsigned char high = FromHex((unsigned char)str[++i]);
unsigned char low = FromHex((unsigned char)str[++i]);
strTemp += high * 16 + low;
}
else strTemp += str[i];
}
return strTemp;
}
class CHttpPost
{
public:
CHttpPost(std::string strServerIP, int sServerPort)
{
m_sServerPort = sServerPort;
m_strServerIP = strServerIP;
}
int SendPostRequest(std::string strUrl, std::string strPostData, char* pszRecvData)
{
std::string strUrlEnCodedBuffer = UrlEncode(strPostData);
io_service iosev;
ip::tcp::socket socket(iosev);
ip::tcp::endpoint ep(ip::address_v4::from_string(m_strServerIP), m_sServerPort);
boost::system::error_code ec;
do
{
socket.connect(ep, ec);
if (ec) break;
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "POST " << strUrl << " HTTP/1.1\r\n";
request_stream << "Host: " << m_strServerIP << ":" << m_sServerPort << "\r\n";
request_stream << "Content-Length: " << strUrlEnCodedBuffer.size() << "\r\n";
request_stream << "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n";
request_stream << "\r\n";
request_stream << strUrlEnCodedBuffer;
size_t len = boost::asio::write(socket, request, ec);
if (ec) break;
char szRecvBuf[1024] = { 0 };
int nReadLen = socket.read_some(buffer(szRecvBuf), ec);
std::cout << "Http Response Context:" << std::endl;
std::cout << szRecvBuf << std::endl;
if (ec) break;
strcpy_s(pszRecvData, nReadLen+1, szRecvBuf);
std::string strRecvBuf = szRecvBuf;
int nIndexOfBody = strRecvBuf.find("\r\n\r\n", 0);
if (nIndexOfBody < 0) return -1;
std::string strHttpBody = strRecvBuf.substr(nIndexOfBody + 4);
std::cout << "Http Body Context:" << std::endl;
std::cout << strHttpBody << std::endl;
} while (0);
socket.close();
if (ec) return -1;
return 0;
}
private:
int m_sServerPort;
std::string m_strServerIP;
};
测试代码
char szSrcBuffer[1024] = { "authorJson={loginAccount:\"admin\"}&parmJson={code:\"SheBeiLiXianGaoJingShangChuan\",params:{id:\"3919123496\",remarks:\"fire alarm\",time_alarm:\"2017-1-1\",alarm_source:\"192.168.1.11\"}}" };
char szUrl[256] = { "/cs/restfull/operationRestfullApi/excuteSqlByCode" };
CHttpPost instance("120.77.55.115", 8089);
char szRecvData[1024] = { 0 };
instance.SendPostRequest(szUrl, szSrcBuffer, szRecvData);
return 0;