C++ 怎么实现简单的HTTP请求 C++使用socket发送GET请求【网络】

1次阅读

用socket发GET请求核心三步:解析域名并连接、构造含Host和rn的请求头并关闭写端、循环recv直至读完响应。需注意跨平台初始化、换行符、协议头及错误处理细节。

C++ 怎么实现简单的HTTP请求 C++使用socket发送GET请求【网络】

socket 发送 GET 请求,核心就三步

windows 或 linux 下用原生 sockethttp GET 请求,不依赖第三方库是可行的,但必须手动处理连接、构造请求头、读取响应。关键不是“能不能”,而是“别漏掉换行和协议细节”。

  • 必须用 rn(回车+换行)结尾,单用 n 服务器大概率返回 400 Bad Request
  • 必须带 Host: 头,HTTP/1.1 协议强制要求,否则很多服务(如 nginx、Cloudflare)直接拒收
  • 建议加 Connection: close,避免服务端保持长连接导致 recv() 阻塞或读不全
  • 域名需先用 getaddrinfo() 解析,不能直接传给 connect();IPv4/ipv6 兼容写法比硬写 AF_INET 更稳妥

send() 后一定要 shutdown(SD_SEND)windows)或 shutdown(sockfd, SHUT_WR)(Linux)

很多人卡在“发了请求但 recv 没返回”,本质是 TCP 连接仍处于“可写”状态,服务端等你继续发数据。不主动关闭写端,服务端可能不发响应或延迟发。

  • Windows 下用 shutdown(sockfd, SD_SEND),不是 closesocket()
  • Linux 下对应 shutdown(sockfd, SHUT_WR)
  • 这一步之后再 recv(),才能让服务端明确知道请求结束,开始回包
  • 忽略它,recv() 可能阻塞、超时,或只读到部分响应(比如只有 status line)

读响应时别假设一次 recv() 能读完

HTTP 响应可能分多次到达,尤其 Body 较大时。直接 recv(buf, sizeof(buf)-1, 0) 一次读,大概率截断。

  • 先读状态行,解析出 Content-Length: 或检测 Transfer-Encoding: chunked
  • 若含 Content-Length: 1234,就循环 recv() 直到累计读够 1234 字节
  • 若为 chunked,需实现 chunk 解析(每块以十六进制长度开头 + rn + 数据 + rn),复杂度陡增——简单场景尽量避免
  • 至少加个循环:while (bytes = recv(…)) > 0,直到返回 0(对端关闭)或 -1(错误)

跨平台编译前记得初始化和清理

Windows 和 Linux 的 socket 初始化差异极大,不处理会直接 crash 或 connect 失败。

立即学习C++免费学习笔记(深入)”;

  • Windows 必须调 WSAStartup(),且在 main() 开头;程序退出前调 WSACleanup()
  • Linux 不需要初始化,但 close() 替代 closesocket()
  • SOCKET 类型在 Windows 是 unsigned int,Linux 是 int,混用会导致编译失败或运行异常
  • 错误检查别只看 == -1:Windows 返回 SOCKET_ERROR,Linux 才是 -1;统一用 if (sock == INVALID_SOCKET)(Windows)或 if (sock (Linux)

实际最易出错的不是写请求,而是读响应时没处理分包、没关写端、没校验 Host 头——这些点漏一个,请求就静默失败。

text=ZqhQzanResources