据我所知,没有办法从网络外部向本地网络中的计算机发送数据包,除非我们知道路由机制由路由器使用。
假设我们有一个如下的设置:
计算机-A,IP 192.168.1.2(默认网关 192.168.1.1)
计算机-B,IP 192.168.1.3(默认网关192.168.1.1)
路由器-C,IP 192.168.1.1(外部 IP 1.1.1.1)
路由器-D(外部IP 2.2.2.2)
计算机 A、计算机 B 和路由器 C 属于同一本地网络。路由器 D 想要向计算机 A 发送数据,但是必须经过路由器 C 才能完成此操作。
现在,如果目标端口为 1000,路由器 C 会将数据包转发到计算机 A;如果目标端口为 2000,路由器 C 会将数据包转发到计算机 B。但可以肯定的是,唯一知道这一点的设备路由机制是路由器 C 本身!计算机 A 和计算机 B 都不知道它,对吧?
因此,如果路由器 D 通过端口 1000 向路由器 C 发送数据包,那么路由器 D 也可以向计算机 A 发送数据包,但是路由器 D 如何知道要通过端口 1000 发送数据包,而不是通过端口 1001 发送?
点对点程序(如 Bittorrent)如何解决这个问题?我能想到的唯一解决方案是让路由器 D 通过全部端口,以便将其转发到计算机 A,但是有没有更好的解决方案?
答案1
您的困惑源于一些错误的假设。
但可以肯定的是,唯一知道此路由机制的设备是路由器 C 本身!甚至计算机 A 和计算机 B 都不知道它,对吗?
什么,为什么?那么为什么路由器配置为将这些端口转发到这些 IP?您必须设置 P2P 客户端以使用特定端口,然后设置路由器进行对应。
但是 Router-D 如何知道通过端口 1000 发送数据包,而不是端口 1001 呢?
因为您将 P2P 客户端配置为使用特定端口(该协议的标准或非标准端口)。
我能想到的唯一解决方案是让路由器 D 通过所有端口将数据包发送到路由器 C,以便将其转发给计算机 A,但有没有更好的解决方案呢?
其实比这简单多了。当客户端与对等端建立连接时,它会指定要使用的端口,这样对等端就会在该端口上发送数据。
嗯,但是 Bittorrent 不会改变路由器的行为,对吧?由于某些路由机制可能是动态的,如 superuser.com/a/187190/78897 中所示,那么 Computer-A 怎么能知道呢?
客户端没有直接地影响路由器,但路由器可以配置/智能到足以适应客户端的行为。您可以启用即插即用在路由器和客户端中自动配置连接,大多数路由器都有状态检测作为其能力的一部分转发端口机制。
总之,这意味着可以在随机端口上动态建立连接,然后路由器可以跟踪正在发生的事情,而不是将所有内容视为随机、无意义的连接。这样,它可以根据需要转发连接,因为例如,这是对刚刚发生的另一个联系的回应。
当您有多个系统使用同一个程序时,问题就出现了。多个系统连接到同一个路由器,共享同一个 IP 并使用动态端口,很快就会变得难以管理,即使使用状态检查,也很难甚至不可能使其正常工作。在这种情况下,需要使用静态端口(默认或其他)。
如果你使用类似智能嗅探或者TCP查看器为了监控您的连接,您会注意到 P2P 连接通常会将您配置的端口(或客户端的默认端口)作为传入连接的目标,并将默认或自定义/随机端口作为源,反之亦然。
答案2
您的问题触及了互联网的核心和路由的定义。在您的示例中,路由器 D 根据两个前提将数据发送到计算机 A:
- 它被告知要将数据发送到计算机 A。
- 它已经处理了来自计算机 A 的数据。
您的场景似乎假设了第一个选项 - 路由器 D 想要发送到计算机 A。但它如何到达那里?它通过使用路由表这些路由器彼此之间共享。
路由器 C 定期向其所知的所有路由器(包括路由器 D)发送更新,告知它“知道” “192.168.*” 网络(实际上,这不会发生,因为该网络未路由,它被视为私有网络。但请忽略这一点。)因此,路由器 D 已经知道路由器 C 知道该网络。
因此,当数据发往计算机 A 时,首先通过网络寻址。因此,路由器 D 询问:“我需要找到 192.168.* 网络。我知道吗?不知道。我认识其他人吗?是的。路由器 C 知道。我如何到达路由器 C?通过我的 2.2.2.2 接口。”
然后,路由器 D 将数据发送到路由器 C。路由器 C 获取数据后会说:“哦,我有来自路由器 D 的数据,但它是用于 192.168 网络的。我知道该网络吗?是的,通过我的 192.168.1.1 网络”,然后将其转发。
解决 IP 和 MAC 寻址还需要做一些其他工作,但我介绍的是路由本身,而不是 ARP 和本地网络。
您会注意到,您的第一个假设 - 远程路由器必须知道路由机制 - 在这里不起作用。路由器 D 不关心路由器 C 使用的是 EIGRP、RIP、RIPv2、OSPF 还是其他。它只关心它是否获得了更新。(当然,如何更新很重要,以确保两者保持同步。但同样,这是另一个问题。)
您的第二个假设 - 端口号是路由的一个因素 - 也是错误的。路由器(通常)不需要端口信息来做出路由决策。(由于一些新的网络技术,这种情况略有改变,主要适用于防火墙和代理,但更广泛的假设仍然适用于“真正的”路由器。)
继续您的示例,路由器 C 将在端口 1000 上转发数据(根据您的情况),因为计算机 A 上的服务可能期望该特定端口上的数据。但它只知道这样做,因为路由器 D 在端口 1000 上发送了数据。路由器 D 只在该端口上发送数据,因为数据的发起者在该端口上将其发送给路由器 D。
我不明白您提到 bittorrent 或 P2P 程序是否反映了您的问题。同样的解释也适用。路由器还可以配置端口触发,将特定设备(或 IP)与特定端口关联起来。这样,当流量进入端口 1234 时,路由器就知道将数据发送到设备 ABCD。这通常与传出 TCP 端口相关联。即,如果我在端口 7890 上发送流量,路由器就会知道传入流量将在端口 1234 上并将其发送给我。
但是端口触发与(远程)路由决策无关 - 而是与路由器用于 LAN 的内部 MAC/IP 表有关。
更新/编辑:在您的评论之后进一步回答和阐述。路由器 D 仅通过其 IP 地址 (192.168.2.2) 知道计算机 A。但路由器 C 通过其 IP 地址和 MAC 地址知道计算机 A。MAC(媒体访问控制)是一个唯一的(通常...)48 位标识符,由国际标准定义。连接到 LAN(有线和无线)的每个设备都应该有一个唯一的 MAC 地址。
路由器(路由器 C)将 IP 地址和 MAC 地址关联到一个表(MAC 地址表)中。因此,当流量进入路由器 C 时,路由器会意识到它是“本地”的,它会进行 MAC 地址表查找。然后路由器会直接更改帧寻址信息。
它重建(重写)第 2 层目标信息以具有计算机 A 的目标 MAC 地址,但保持 IP 地址信息(第 3 层)保持不变。
如果路由不知道 MAC 地址。或者其表中没有 IP-MAC 关系,它会执行称为 ARP(地址解析协议)的操作来询问“嘿,这个网络上的每个人。你有这个 MAC 地址吗?”或者有时是“大家,你的 MAC 地址是什么?”)。相应的设备会做出响应,路由器会构建其 IP-MAC 表。
答案3
端口触发。在您请求网页后,Web 服务器如何向您发送网页?因为您已经请求了它。当您请求它时,路由器知道会收到回复,当它收到回复时,它会将其转发到相应的 PC。有些程序被编写为在预期来自特定 PC 的信号时触发端口打开,即使实际上没有 PC 在发送信号。
有些型号有一个用于基本通信的中央服务器。例如:
- Client1 与服务器登录以进行双向通信。
- 客户 2 也签到做同样的事情。
服务器现在知道客户端 1 和客户端 2 拥有的所有文件。
- Client2 向服务器说“我想要 Client1 上的文件 X”。
- 服务器告诉客户端1“客户端2想要X文件。”
- 客户端 1 向客户端 2 的公网 IP 发送一段垃圾数据,触发端口触发,因此它打开端口以接收来自客户端 2 的回复。
- Client2 将其初始信号发送到 Client1 的公共 IP。
Client1 只是欺骗路由器为 Client2 开放该端口。
在某些情况下,例如 BitTorrent 或原始 Napster(iirc),您必须在路由器上转发端口才能使其最佳地工作。
至于其他客户端最初知道要连接到哪个端口,这是因为您的客户端告诉了群集或服务器您使用哪个端口。BitTorrent 经常使用跟踪器,它可以跟踪哪些客户端使用了哪些端口。