C Socket编程HTTP请求:成功请求后的错误请求

C Socket programming HTTP request: bad request after successful request

我正在学习使用 C 进行套接字编程。我正在尝试发出 HTTP 请求并获得响应。

我将响应放入名为“response.txt”的文件中。因为我不知道响应会有多长时间,所以我将 recv() 放在一个 while 循环中,将接收到的内容附加到“response.txt”,并在套接字接收到 0 个字节时中断循环。

我的问题是我收到了 2 个回复。一个是“HTTP/1.1 200 OK”,另一个是“HTTP/1.1 400 Bad Request”.

我想知道为什么会这样。是因为我的代码中存在一些不需要的错误,还是因为某些网络或协议设计?

这是与http请求相关的代码部分。

// create socket
int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct hostent *server = gethostbyname(www_ip); // www_ip is command line argument
struct sockaddr_in addr; 
memset(&addr, 0, sizeof(addr)); 
addr.sin_family = AF_INET; 
addr.sin_addr.s_addr = * (unsigned long *) server->h_addr_list[0];
addr.sin_port = htons(80);
// connect
int connection_status = connect(sockfd, (struct sockaddr *) &addr, sizeof(addr));

// sending HTTP request
char test_msg[] = "GET /code/romeo.txt HTTP/1.1\r\nHost: www.py4inf.com\r\n\r\n";
int byte_sent;
byte_sent = send(sockfd, test_msg, sizeof(test_msg), 0);

// receiving HTTP response
char recv_data[1000];
int byte_recv;
FILE* fp = fopen("response.txt", "a");
while (1){
    byte_recv = recv(sockfd, &recv_data, 1000, 0);
    if (byte_recv == -1) {
        exit(-1);
    }
    if (byte_recv == 0) {
        break;
    }
    fputs(recv_data, fp);
}
fclose(fp);

// close connection
close(sockfd);

这是response.txt中的内容。

“Who is already sick and fale with grief”这一行应该是所请求文件的最后一行。但在那之后有一个“HTTP/1.1 400 Bad Request”

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 167
Connection: keep-alive
Keep-Alive: timeout=15
Date: Sun, 27 Feb 2022 16:38:11 GMT
Server: Apache
Last-Modified: Fri, 04 Dec 2015 19:05:04 GMT
ETag: "a7-526172f58b800"
Accept-Ranges: bytes
Cache-Control: max-age=604800, public
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: origin, x-requested-with, content-type
Access-Control-Allow-Methods: GET

But soft what light through yonder window breaks
It is the east and Juliet is the sun
Arise fair sun and kill the envious moon
Who is already sick and pale with grief
HTTP/1.1 400 Bad Request
Server: nginx
Date: Sun, 27 Feb 2022 16:38:11 GMT
Content-Type: text/html
Content-Length: 150
Connection: close

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
c
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: origin, x-requested-with, content-type
Access-Control-Allow-Methods: GET

But soft what light through yonder window breaks
It is the east and Juliet is the sun
Arise fair sun and kill the envious moon
Who is already sick and pale with grief

char test_msg[] = "GET /code/romeo.txt HTTP/1.1\r\nHost: www.py4inf.com\r\n\r\n";
int byte_sent;
byte_sent = send(sockfd, test_msg, sizeof(test_msg), 0);

sizeof(test_msg)是请求的长度加一。这意味着它不仅会发送请求,还会发送字符串末尾的 [=12=]。这将被读取为下一个 - 错误的请求。

而不是 sizeof(test_msg) 使用 strlen(test_msg) - 它给出字符串的大小而不是字符串缓冲区。