You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++使用POCO发起POST请求状态200但receiveResponse抛Poco::Net::NoMessageException

异常触发原因
  • 核心协议不匹配:你请求的目标地址是HTTPS协议,但代码中使用了仅支持HTTP的Poco::Net::HTTPClientSession发起请求,没有完成TLS握手流程,服务端直接断开连接,导致无法读取响应报文,触发NoMessageException。你之前打印的200 OK是Poco::Net::HTTPResponse对象的默认初始化值,并非服务端真实返回的状态。
  • 调用逻辑错误:你在执行session.receiveResponse(response)之前就调用了response.getStatus()、response.getReason()方法,receiveResponse才是负责从网络连接中读取响应头、填充response对象的接口,提前访问只会拿到默认值,也不会提前触发响应读取逻辑。
解决方案

按以下步骤修改代码即可解决问题:

  1. 替换HTTP会话类为HTTPS专用类,同时初始化NetSSL库上下文(使用HTTPS必须依赖Poco的NetSSL模块,编译时要链接对应的库)
  2. 调整响应信息打印的顺序,放在receiveResponse调用之后
  3. 请求体写入完成后调用flush()确保数据全部发送到网络

修正后代码示例:

// 需要引入HTTPS相关头文件
#include <Poco/Net/HTTPSClientSession.h>
#include <Poco/Net/SSLManager.h>
#include <Poco/Net/AcceptCertificateHandler.h>
#include <Poco/SharedPtr.h>

// 初始化SSL上下文(程序启动时执行一次即可)
Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> pCertHandler = new Poco::Net::AcceptCertificateHandler(false);
Poco::Net::Context::Ptr pContext = new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE, "", "", "rootcert.pem");
Poco::Net::SSLManager::instance().initializeClient(0, pCertHandler, pContext);

//Uri for fake tests
Poco::URI uri("https://fakestoreapi.com/products");
// 替换为HTTPSClientSession
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());
session.setKeepAlive(true);
session.setTimeout(Poco::Timespan(20,0));

std::string path(uri.getPathAndQuery());
if(path.empty()) path = "/";

Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, path, Poco::Net::HTTPMessage::HTTP_1_1);
request.setContentType("application/json");
        
Poco::JSON::Object jsonObj;
std::stringstream strStream;

//Dummy data
jsonObj.set("title", "Test product");
jsonObj.set("price", "1520");
jsonObj.set("category", "electronics");
jsonObj.stringify(strStream);

request.setContentLength(strStream.str().size());

std::ostream& os = session.sendRequest(request);
os << strStream.str();
os.flush(); // 确保请求体全部发送

Poco::Net::HTTPResponse response;  
// 先调用receiveResponse填充响应对象
std::istream& inputStream = session.receiveResponse(response); 

// 再打印响应信息
std::cout << "Response status = " << response.getStatus() << std::endl;
std::cout << "Response Reason = " << response.getReason() << std::endl;   
std::cout << response.getContentLength() << std::endl;

Poco::StreamCopier::copyStream(inputStream, std::cout);

注:示例中使用AcceptCertificateHandler是为了方便测试,生产环境请替换为合法的证书校验逻辑,避免安全风险。

内容的提问来源于stack exchange,提问作者MHerreraJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 16:57:01