例子

std::string strUrlEnCodedBuffer = UrlEncode(strPostData);

//使用Boost库asio组件的时候,建立的套接字,如果没有设置TIME_WAIT的资源销毁时间,会导致网络套接字回收缓慢

       io_service iosev;

       ip::tcp::socket socket(iosev);

       socket.open(boost::asio::ip::tcp::v4());

       boost::asio::socket_base::linger option(true, 0);

       socket.set_option(option);

//采用asio库的时候,需要更多的注意ec的使用,否则需要使用try catch捕获异常,否则导致程序崩溃

       ip::tcp::endpoint ep(ip::address_v4::from_string(m_strServerIP), m_nServerPort);

       boost::system::error_code ec;

       do

       {

              socket.connect(ep, ec);

              if (ec)

              {

                     LOG4CPLUS_ERROR(LOGGERTAG, "can not connect ip:" << m_strServerIP << ",port:" << m_nServerPort);

                     break;

              }

//一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成。使用C++组装上述报文

              boost::asio::streambuf request;

              std::ostream request_stream(&request);

//请求行

              request_stream << "POST " << strUrl << " HTTP/1.1\r\n";

//请求头部

              request_stream << "Host: " << m_strServerIP << ":" << m_nServerPort << "\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";

//请求数据 (请求数据不在GET方法中使用,而是在POST方法中使用)

              request_stream << strUrlEnCodedBuffer;

              size_t len = boost::asio::write(socket, request, ec);

              if (ec)

              {

                     LOG4CPLUS_ERROR(LOGGERTAG, "can not write ip:" << m_strServerIP << ",port:" << m_nServerPort);

                     break;

              }

 

              char szRecvBuf[102400] = { 0 };

              int nReadLen = socket.read_some(buffer(szRecvBuf), ec);

              if (ec)

              {

                     LOG4CPLUS_ERROR(LOGGERTAG, "can not read ip:" << m_strServerIP << ",port:" << m_nServerPort);

                     break;

              }

              strcpy_s(pszRecvData, nReadLen + 1, szRecvBuf);

              std::string strRecvBuf = szRecvBuf;

              //HTTP协议报文检验

              if ("HTTP" == strRecvBuf.substr(0, 4))

              {

                     //状态码检验

                     if ("200" == strRecvBuf.substr(9, 3))

                     {

                            nResult = 0;

                     }

              }

       } while (0);

       socket.close();

       return nResult;

}

常见状态代码、状态描述的说明如下。

•• 200 OK:客户端请求成功。

•• 301 Moved Permanently:客户端啊,要请求的资源已经永久的搬家了,我把他的新地址放到了Location头部域中了;

••302 Moved Temporarily:客户端啊,你要请求的资源临时有事去别的地方了,我把他的位置放到了Location头部域中了,你可以先去那里找他,不过他应该是会回到他自己的家的;

••304 Not Modified:客户端啊,你要请求的资源自从上次你请求之后,就再也没有改动过,我想你是应该早就有这个资源了,所以在响应报文的数据部分我也没有再放这个资源。

•• 400 Bad Request:客户端请求有语法错误,不能被服务器所理解。

•• 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。

•• 403 Forbidden:服务器端顺利收到了客户端的请求,但是服务器端拒绝为他提供服务

•• 404 Not Found:请求资源不存在,八成是资源地址写错了;输入了错误的URL。

•• 500 Internal Server Error:服务器发生不可预期的错误。

•• 502 Bad Gateway:请求报文的代理服务器,持有资源的那个服务器在给我发送资源时出问题了

•• 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常