Nodejs - HTTP 响应如何始终命中正确的设备?

Nodejs - How do HTTP responses always hit the right device?

大家好!前段时间问过。在获得有用的回复后,我了解到网络在设计上无法直接区分连接到同一路由器的设备。

因此,例如,下面的代码永远无法 100% 发挥作用...

require('http').createServer((req, res) => {

    let uniqueDeviceId = getUniqueDeviceId(req);

}).listen(80, '<my public ip>', 511);

... 因为无法以有保证的方式实施 getUniqueDeviceId。它不能只是 return req.connection.remoteAddress,因为多个设备可能具有相同的地址。

鉴于此,我的问题是:res.end(...) 如何始终响应正确的设备?

例如考虑这个简单的服务器:

require('http').createServer((req, res) => {

    res.end(req.url);

}).listen(80, '{{my public ip}}', 511);

以连接到同一 IP 地址的两个不同设备为例。每个设备都使用自己的 url:

现在这两种设备每秒以数千个请求轰炸它们的 url。

作为响应,设备 1 将始终获得 /device1,而设备 2 将始终获得 /device2,即使这种配置会导致竞争条件!

即使 I 无法直接确定设备的唯一 ID,res.end 将始终对应于适当的 req - 它永远不会出错并且向一些不同的 req 发送响应,即使在几乎完全相同的时间从相同的 IP 地址接收到不同的 req。对我来说,这证明在某种程度上,比 Nodejs 更低,可以确定唯一的设备 ID。

如果这是正确的,那么在 HTTP 体系结构的哪个级别我们可以保证响应将始终返回到其初始请求者?这是如何实现的?

"To me this is proof that at some level, lower than Nodejs, unique device IDs can be determined"

-- 不,不是可以确定的"unique device ID",而是确定的唯一"IP - Port"组合

例如,在您的情况下,设备 1 和设备 2 隐藏在路由器后面,这使得它们的 IP(路由器的 IP)与您的 Web 服务器相同。但是,尽管它们具有相同的 IP,但它们的端口却不同。

对于设备 1,从您的 Node.js 网络服务器的角度来看,套接字(SourceIP/Port - DestinationIP/Port 的组合)可能是:

{{RouterIP}}:{{PortX}} - {{Node.js serverIP}}:{{Node.js serverPort}}

对于设备 2,从您的 Node.js 网络服务器的角度来看,套接字可能是:

{{RouterIP}}:{{PortY}} - {{Node.js serverIP}}:{{Node.js serverPort}}

因此,虽然设备1和设备2的IP相同,但是HTTP响应会返回到路由器的相应端口——设备1的响应将返回到路由器的PortX,而设备2的响应将是返回 PortY。

然后,在路由器内部,有一个映射,如:

{{PortX}} - {{Device 1's private IP}}:{{Device 1's Port}}
{{PortY}} - {{Device 2's private IP}}:{{Device 2's Port}}

因此,返回到路由器 PortX 的响应将被重定向到设备 1(及其对应的端口),返回到 PortY 的响应将被重定向到设备 2。

这叫做NAT,上面的描述只是一个很简单的例子。

"what level of HTTP architecture do we get the guarantee that a response will always go back to its initial requester? And how is this implemented?"

-- 这与HTTP无关,属于IP层。实现发生在路由器中。 Web 应用程序开发人员不需要做任何事情。

MAC 地址确实 "uniquely" 识别设备。但即使是:

首先:http 在 tcp/ip 之上。 IP 是定义网络中设备位置的标准。设备从它们的路由器获取 IP,并且设备可以发送到路由器到它们自己的 IP。 (192.168.2.1:80(路由器) -> 192.168.2.100:80(PC))

路由器然后通过您的 ISP 将内容发送到 WWW。

您的 public IP -请求> ISP -请求> 目标IP -回答> ISP -答案>

(这一切都是在包的 IP 和端口保存在包裹在其他数据包中的包中时发生的。大多数时候还有比这些更多的跃点。)


然后是端口:如果你使用一个端口,它会被设备本地阻止。如果没有端口,TCP/IP 就会有你提到的那些竞争条件,因为它们会互相阻塞。


事情是这样的:您没有使用不同的端口或 IP。因此,无论您在做什么,都只是让一个服务器处理两个传入请求,否则试图阻止该端口的第二个服务器将无法执行,因为它不符合 TCP/IP。 您将无法让 IP1:80/device1 和 IP1:80/device2 运行 2 个不同的应用程序试图阻止端口 80。

所以你是对的(会有差异)但也被 2 服务器能够 运行 端口 80 的想法误导。

他们处理你所说的案例的方式如下:

两者之一

  • 使用Apache/Nginx/Nodejs并制作一个主应用程序(路由器)通过反向代理和其他类型的*查询方法将查询重定向到服务器。
  • 使用不同的端口[=52​​=]

澄清一下:HTTP 如下:

  • 路径(/this/is/a/path)
  • Headers(这些你并没有真正看到,但它们包含缓存提示、数据类型和文件处理,关于文件应该如何处理以及作为什么和安全)

服务器对 HTTP 所做的是使用它们从 HTTP 格式获得的数据。 (这只是 TCP 中数据的特定布局) 并用它来确定path/route结果的位置。

shaochuancs 提到的套接字处理是 TCP 和 UDP 的一部分,这两个低级协议。 网络大约有 7 层。所以这只是整个故事的一部分。如果您有兴趣了解更多信息,请专门在 Google 上搜索网络层。这是一个很好的关键字来获得更多关于这个东西的信息。