我正在学习在 OS X 机器上使用 C 和 C++ 中的 native 套接字。在之前的项目中,我在 http://castifyreceiver.com/index.html 设置了一个非常简单的网页。 。该网页几乎不再执行任何操作,因此我不介意分享真实的 URL。
基本上我的问题是我的所有 HTTP 请求都返回 400 Bad Request。我知道我用于此练习的网页已启动并正在运行,并且我可以通过浏览器访问它。这让我相信我错误地实现了 HTTP 协议(protocol),但我不知道哪里出了问题。
以下是我用来通过套接字请求此页面的所有代码。
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
int main(int argc, const char * argv[]) {
// create the request
const char * request = "GET /index.html HTTP/1.1\nAccept: */*\n\n";
size_t length = strlen(request);
printf("request:\n\n%s", request);
// get the destination address
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
struct addrinfo * address;
getaddrinfo("castifyreceiver.com", "http", &hints, &address);
// create a socket
int sfd = socket(address->ai_family, address->ai_socktype, address->ai_protocol);
int result = connect(sfd, address->ai_addr, address->ai_addrlen);
if (result != 0) {
printf("connection failed: %i\n", result);
freeaddrinfo(address);
close(sfd);
return 0;
} else {
printf("connected\n");
}
// write to socket
ssize_t written = write(sfd, request, length);
printf("wrote %lu of %lu expected\n", written, length);
// read from socket and cleanup
char response[4096];
ssize_t readed = read(sfd, response, 4096);
printf("read %lu of 4096 possible\n", readed);
close(sfd);
freeaddrinfo(address);
// display response message
response[readed] = '\0';
printf("response:\n\n%s\n", response);
return 0;
}
该程序始终输出类似于以下内容的内容:
request:
GET /index.html HTTP/1.1
Accept: */*
connected
wrote 38 of 38 expected
read 590 of 4096 possible
response:
HTTP/1.1 400 Bad Request
Date: Thu, 05 Nov 2015 18:24:08 GMT
Server: Apache/2.2.31 (Unix) mod_ssl/2.2.31 OpenSSL/1.0.1e-fips mod_bwlimited/1.4
Content-Length: 357
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand. <br />
</p>
<hr>
<address>Apache/2.2.31 (Unix) mod_ssl/2.2.31 OpenSSL/1.0.1e-fips mod_bwlimited/1.4 Server at 108.167.131.50 Port 80</address>
</body></html>
我花了很多时间查看RFC 2616我仍然找不到我做错了什么。如有任何帮助,我们将不胜感激。
最佳答案
有两件事:
您必须发送
Host
header ,参见。 RFC 2616 页。 129:A client MUST include a Host header field in all HTTP/1.1 request messages . If the requested URI does not include an Internet host name for the service being requested, then the Host header field MUST be given with an empty value.
使用
\r\n
终止 HTTP 中的行,而不仅仅是\n
,参见RFC 2616 页。 16:HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all protocol elements except the entity-body (see appendix 19.3 for tolerant applications). The end-of-line marker within an entity-body is defined by its associated media type, as described in section 3.7.
如果你改变它应该会起作用。
关于C/C++ Posix BSD 套接字 - HTTP 请求始终返回状态 400,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33552232/