如何使用WinHTTP实现联网计算机间双向数据收发
WinHTTP实现跨机器双向数据收发方案
WinHTTP是系统原生HTTP客户端组件,配合自定义轻量HTTP服务端即可在不依赖IIS、不使用135/445端口的前提下完成双向数据传输,核心逻辑遵循标准HTTP请求-响应模型:客户端发起请求时携带上行数据,服务端解析请求后返回响应携带下行数据。
客户端(WinHTTP侧)发送数据的实现
你当前写的是无请求体的GET请求,要发送上行数据只需要做少量修改,优先使用POST方法承载请求体:
- 将
WinHttpOpenRequest调用中的请求方法参数从_T("GET")修改为_T("POST") - 提前准备好待发送的字节数据,计算准确的字节长度
- 若要发送小体量数据,直接在
WinHttpSendRequest调用中传入数据指针和长度即可,无需再传WINHTTP_NO_REQUEST_DATA宏;若发送大文件等大体量数据,可先传WINHTTP_NO_REQUEST_DATA发起请求,再循环调用WinHttpWriteData分块写入数据 - 按需添加
Content-Type请求头,标明发送数据的格式,避免服务端解析失败
核心修改代码示例:
// 待发送的上行数据示例 const char* uploadData = "Test upload payload from WinHTTP client"; DWORD uploadDataLen = static_cast<DWORD>(strlen(uploadData)); // 创建POST请求,若使用HTTP而非HTTPS请移除WINHTTP_FLAG_SECURE标记 hRequest = WinHttpOpenRequest( hConnect, _T("POST"), L"/data", // 请求路径可自定义 NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0 ); // 添加请求头 LPCWSTR reqHeaders = L"Content-Type: application/octet-stream\r\n"; WinHttpAddRequestHeaders(hRequest, reqHeaders, -1, WINHTTP_ADDREQ_FLAG_ADD); // 发起请求并携带上行数据 bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, reinterpret_cast<LPVOID>(const_cast<char*>(uploadData)), uploadDataLen, uploadDataLen, 0 );
请求发送成功后,你原有读取响应的逻辑无需大幅修改,即可正常获取服务端返回的下行数据。
对端服务端回传响应的实现
对端无需部署IIS,直接基于原生TCP接口实现极简HTTP服务端即可,C/C++下可直接调用系统自带的WinSock2 API开发,成熟稳定无额外依赖,实现逻辑如下:
- 初始化WinSock环境,创建TCP套接字,绑定自定义未占用端口(避开135/445等系统保留端口即可,注意在对端防火墙放开该端口的入站规则),启动监听
- 接受到客户端的TCP连接后,按HTTP协议规范读取请求内容:先解析请求头获取
Content-Length字段值,再按该长度读取完整请求体,即为客户端通过WinHTTP发送的上行数据 - 完成业务逻辑处理后,按标准HTTP响应格式拼接返回报文,报文结构固定为:响应状态行 + 响应头 + 空行 + 实际回传数据,示例格式如下:
HTTP/1.1 200 OK Content-Type: application/octet-stream Content-Length: 13 Connection: close Hello Client!
- 将拼接好的完整响应报文通过TCP连接发送给客户端,关闭对应连接即可,客户端的WinHTTP逻辑会自动解析该响应,把响应体内容返回给你已有的读数据逻辑。
现有测试代码的问题修正
你贴的GET请求测试代码存在几个稳定性问题,需要调整:
pszOutBuffer定义时未初始化为NULL,若读取数据的循环未执行,后续delete[] pszOutBuffer会触发未定义行为,需在定义时赋值为NULL,释放前判空- 固定1024字节的
sResult缓冲区如果接收超过长度的响应会被StringCchPrintfA截断,建议根据实际接收的数据长度动态扩容缓冲区 - 测试自定义服务端时,将
WinHttpConnect中的目标地址从www.microsoft.com改为对端机器IP,端口号改为服务端实际监听的端口即可。
关于原生TCP方案的补充
Windows平台C/C++原生TCP编程直接使用WinSock2 API即可,系统全版本兼容,公开的成熟实现案例非常多,如果不需要HTTP协议的兼容性,裸TCP传输的性能更高,仅需要自行处理分包、粘包逻辑即可,开发复杂度略高于HTTP方案。
内容的提问来源于stack exchange,提问作者JeffR
相关产品推荐
相关产品推荐

