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:
- 设备 1 使用
http://{{my public ip}}/device1
- 设备 2 使用
http://{{my public ip}}/device2
现在这两种设备每秒以数千个请求轰炸它们的 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 上搜索网络层。这是一个很好的关键字来获得更多关于这个东西的信息。
大家好!前段时间问过
因此,例如,下面的代码永远无法 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:
- 设备 1 使用
http://{{my public ip}}/device1
- 设备 2 使用
http://{{my public ip}}/device2
现在这两种设备每秒以数千个请求轰炸它们的 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 上搜索网络层。这是一个很好的关键字来获得更多关于这个东西的信息。