C Socket编程HTTP请求:请求成功后出现错误请求
我正在使用 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中的内容。
“谁已经病了,因悲伤而脸色苍白”这行应该是所请求文件的最后一行。但之后出现“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
I am learning socket programming using C. I am trying to make HTTP request and get its response.
I put the response into a file called "response.txt". Since I have no idea how long the response will be, I put the recv() inside a while loop, append the received content to "response.txt", and break the loop when the socket receives 0 bytes.
The question I have is that I am receiving 2 responses. One is "HTTP/1.1 200 OK", another one is "HTTP/1.1 400 Bad Request".
I want to know why this happen. Is it because there is some unwanted bug in my code, or is it because of some networking or protocol design?
This is the part of the code related to http requests.
// 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);
This is the content in response.txt.
The line "Who is already sick and pale with grief" supposed to be the last line of the requested file. But after that there is a "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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
sizeof(test_msg)
是请求的长度加一。这意味着它不仅会发送请求,还会发送字符串末尾的\0
。这将被视为下一个错误的请求。使用
strlen(test_msg)
而不是sizeof(test_msg)
- 它给出字符串的大小,而不是字符串缓冲区的大小。sizeof(test_msg)
is the length of the request plus one. This means it will send not only the request but also the\0
for the end of the string. This will be read as the next - and wrong request.Instead of
sizeof(test_msg)
usestrlen(test_msg)
- which gives the size of the string and not the string buffer.