Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets C编程-发送HTTP请求_Sockets_Httprequest_Rfc - Fatal编程技术网

Sockets C编程-发送HTTP请求

Sockets C编程-发送HTTP请求,sockets,httprequest,rfc,Sockets,Httprequest,Rfc,我最近的任务是使用socket编程在C中创建一个代理。代理只需要使用HTTP/1.0构建。经过几个小时的工作,我制作了一个可以与铬一起使用的代理。可以加载各种网站,如谷歌和几个.edu网站;然而,许多网站给了我一个404错误页面未找到(这些链接工作正常时,不通过我的代理)。这些404错误甚至发生在站点的根地址“/”上。。。这没有道理 这可能是我的HTTP请求有问题吗?从浏览器发送的HTTP请求被解析为HTTP请求方法、主机名和端口。例如,如果从浏览器解析GET请求,则会建立到提供的主机名和端口的

我最近的任务是使用socket编程在C中创建一个代理。代理只需要使用HTTP/1.0构建。经过几个小时的工作,我制作了一个可以与铬一起使用的代理。可以加载各种网站,如谷歌和几个.edu网站;然而,许多网站给了我一个404错误页面未找到(这些链接工作正常时,不通过我的代理)。这些404错误甚至发生在站点的根地址“/”上。。。这没有道理

这可能是我的HTTP请求有问题吗?从浏览器发送的HTTP请求被解析为HTTP请求方法、主机名和端口。例如,如果从浏览器解析GET请求,则会建立到提供的主机名和端口的TCP连接,并以以下格式发送HTTP GET请求:

GET /path/name/item.html HTTP/1.0\r\n\r\n
这种格式适用于少量网站,但会为其余网站创建404错误消息。这可能是问题所在吗?如果不是,还有什么可能给我这个问题


任何帮助都将不胜感激。

一个可能的解释是,您已经设计了一个HTTP/1.0代理,而共享托管站点上的任何网站现在都只能使用HTTP/1.1(嗯,不完全是这样,但我马上就谈到)

从长远来看,这并不是唯一可能出现的问题,但你必须给出一个网站的例子,这个网站在获得更多想法时失败了

您似乎理解了HTTP的基本原理,即客户端与服务器建立TCP连接并通过服务器发送HTTP请求,该请求由一个请求行(例如
GET/path/name/item.html HTTP/1.0
)和一组可选的头行组成,所有这些行都由CRLF分隔(即
\r\n
)。整个批次以两个连续的CRLF序列结束,在这一点上,另一端的服务器将请求与资源匹配,并发送回相应的响应。所有资源都由路径(例如,
/path/name/item.html
)标识,该路径可以是真实文件,也可以是动态页面

自从HTTP被发明以来,它的大部分内容几乎没有改变。但是,请考虑客户机如何找到要连接的服务器。您给它的是一个URL,如下所示:

http://www.example.com/path/name/item.html
GET /path/name/item.html HTTP/1.0\r\n
Host: www.example.com\r\n
\r\n
从这一点看,它看到了方案,即
http
,因此它知道它正在进行http连接。下一部分是主机名。在最初的HTTP协议中,假设每个主机名解析为自己的IP地址,然后客户端连接到该IP地址并发出请求。因为当时每台服务器只有一个网站,所以这很好

然而,随着网站数量的增加,很难为每个网站提供不同的IP地址,特别是因为许多网站非常简单,很容易在同一台物理机器上共享。将多个域指向同一IP地址是很容易的(DNS系统使这变得非常简单),但当服务器收到TCP请求时,它只知道它有一个对其IP地址的请求——它不知道要发送回哪个网站。因此,添加了一个新的
Host
头,以便客户端可以在请求本身中指示它请求的主机名。这意味着一台服务器可以承载许多网站,而Web服务器可以使用
host
头来告诉响应中要服务哪个网站

现在这种情况非常普遍——如果你不使用
主机
标题,很多网站都不知道你要的是哪台服务器。通常发生的情况是,他们假设他们拥有的列表中有一些默认网站,很可能这个网站没有你想要的文件。即使您要求
/
,如果您不提供
主机
头,那么Web服务器可能会给您一个404,如果它是这样配置的-如果没有合理的默认网站给您,这也不是不合理的

如果需要更多技术细节,可以在中找到主机的说明

此外,网站可能只是简单地拒绝HTTP/1.0——如果在这么多网站上发生这种情况,我会有点惊讶,但你永远不会知道。不过,请先尝试主机的
标题

与一些人认为的相反,没有什么可以阻止您在HTTP/1.0中使用
Host
头,尽管您可能仍然会发现一些服务器不喜欢它。这比支持完整的HTTP/1.1要容易一些,它要求您理解分块编码和其他复杂性,尽管对于简单的示例代码,您可能只需要添加
Host
头并将其称为HTTP/1.1就可以了(不过,我不认为这对于生产代码是足够的)

无论如何,您可以尝试添加
主机
标题以发出如下请求:

http://www.example.com/path/name/item.html
GET /path/name/item.html HTTP/1.0\r\n
Host: www.example.com\r\n
\r\n
我把它拆开了,只是为了便于阅读——你可以看到在结尾仍然有空行。

即使这并没有引起您所看到的问题,现在的
Host
头也是一个非常好的主意,因为没有它肯定会有网站无法工作。如果你仍然有问题,他们给我一个不适合你的网站的例子,我们可以尝试找出原因


如果我所说的任何内容不清楚或需要更详细的说明,请提问。

非常感谢您的详细回复。我不知道我需要包含主机标题。我把它添加到我的HTTP请求中,一切都开始正常工作了!我感谢你的帮助!不客气。严格来说,你不需要主机的
标题,但正如你所发现的,很多网站没有它就无法工作!很好的解释!我的C客户端的执行在读取时遇到了问题。请参阅我发布的更多详细信息