网络通信第四课 C++发送Post请求的完整案例
说明
当前例子采用boost asio库发送HTTP数据报文,采用boost::asio::streambuf request流封装数据报文,在例子的后面
通过string对响应数据包进行分析,获取其中的json格式数据包
#include
#include
#include
#include
using namespace std;
using namespace boost::asio;
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;
}
int HttpPost()
{
// char szSrcBuffer[1024] = { "authorJson={loginAccount:\"admin\"}&parmJson={code:\"SheBeiLiXianGaoJingShangChuan\",params:{id:\"123456\",remarks:\"fire alarm\",time_alarm:\"2017-1-1\",alarm_source:\"192.168.1.11\"}}" };
char szSrcBuffer[1024] = { "authorJson={loginAccount:\"admin\"}&parmJson={code:\"SheBeiLiXianChaXun\",params:{}}" };
std::string strUrlEnCodedBuffer = UrlEncode(szSrcBuffer);
io_service iosev;
ip::tcp::socket socket(iosev);
ip::tcp::endpoint ep(ip::address_v4::from_string("192.168.0.88"), 8080);
boost::system::error_code ec;
socket.connect(ep, ec);
if (ec) return -1;
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "POST /cs/restfull/operationRestfullApi/excuteSqlByCode HTTP/1.1\r\n";
request_stream << "Host: 192.168.0.88:8080\r\n";
//request_stream << "Connection: keep-alive\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 << "User-Agent: Mozilla/4.0\r\n";
//request_stream << "Accept-Language: zh-CN\r\n\r\n";
request_stream << "\r\n";
request_stream << strUrlEnCodedBuffer;
size_t len = boost::asio::write(socket, request);
char szRecvBuf[1024] = { 0 };
socket.read_some(buffer(szRecvBuf), ec);
std::cout << "Http Response Context:" << std::endl;
std::cout << szRecvBuf << std::endl;
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;
return 0;
}