[英]C Raw Sockets HTTP Request Always Returning Status 400
我通常会写一堆 Typescript/Javascript 代码,我认为 HTTP 协议是理所当然的。 我决定编写一个 C++ 程序,该程序可以使用套接字向给定的 URL 发出 GET 请求,以了解有关 HTTP 工作原理的更多信息。 我已经编码了我认为我应该做的基本结构:
问题是请求总是返回状态码 400:
>>>> Request sent:
GET /links HTTP/1.1
>>>> Response received:
HTTP/1.1 400 Bad Request
Server: cloudflare
Date: Sun, 11 Oct 2020 05:57:11 GMT
Content-Type: text/html
Content-Length: 155
Connection: close
CF-RAY: -
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>cloudflare</center>
</body>
</html>
这是我用来创建套接字并将其连接到主机的代码:
// ---- Create the socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) error("!!!! ERROR opening socket");
// ---- Look up (and parse) the server host, route
std::string host = parseHost(url);
std::string route = parseRoute(url);
struct hostent *server = gethostbyname(host.c_str()); // host.c_str())
if (server == NULL)
error("!!!! ERROR, no such host");
// ---- Fill in the server address structure
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT); // PORT
memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
// ---- Connect the socket to the given url's host
const int didConnect = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (didConnect < 0) error("!!!! ERROR connecting to host");
如果这个逻辑看起来是正确的,那么这里是发送请求和接收响应的代码:
// ---- Send the GET request byte by byte
int bytes, sent, received;
char response[MAX_CONTENT_LENGTH];
int total = sizeof(response) - 1;
sent = 0;
std::string message = "GET " + route + "HTTP/1.1" + "\r\n\r\n";
do
{
bytes = write(sockfd, message.c_str() + sent, total - sent);
if (bytes < 0) error("!!!! ERROR writing message to socket");
if (bytes == 0) break;
sent += bytes;
} while (sent < total);
std::cout << ">>>> Request sent: \n" << message << std::endl;
// ---- Receive the response byte by byte
memset(response, 0, sizeof(response));
total = sizeof(response) - 1;
received = 0;
do {
bytes = read(sockfd, response + received, total - received);
if (bytes < 0)
error("!!!! ERROR reading response from socket");
if (bytes == 0)
break;
received += bytes;
} while (received < total);
if (received == total)
error("!!!! ERROR storing complete response from socket (not enough space allocated)");
"GET /route HTTP/1.1\\r\\n\\r\\n"
。 我是否忘记了让服务器知道这是 GET 请求的任何标头/其他信息?>>>> Request sent:
GET /links HTTP/1.1
这不是有效的 HTTP 请求。 它缺少带有目标域名的 Host 标头,即它至少应该是这样的
GET /links HTTP/1.1
Host: www.example.com
除此之外,您的代码只是尝试读取数据,直到服务器关闭连接或达到内部缓冲区的大小。 但是 HTTP/1.1 默认使用持久连接。 因此,服务器可能会在响应发送后简单地保持连接打开,因为它期待您的下一个请求,这意味着您的程序将简单地阻止什么都不做。
请注意,HTTP 远比看起来复杂。 如果您想实现它而不是使用现有库,请研究实际标准。 这就是标准的用途。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.