(也许只有Unix库的知识才足以回答这个问题,所以如果您不了解JoCaml,请继续阅读。)

我在JoCaml中有两个程序。一台服务器,准备在端口12345上返回数字的平方

(* p.ml *)
def f (x) =
        print_string ("["^string_of_int(x)^"] "); flush stdout;
        reply x*x to f
in Join.Ns.register Join.Ns.here "square" f
;;
let wait =
        def x () & y () = reply to x
        in x
let main =
        Join.Site.listen (Unix.ADDR_INET (Join.Site.get_local_addr(), 12345));
        wait()

和一个客户端,准备使用服务器的平方函数
(* q.ml *)
let server =
        let server_addr = Unix.gethostbyname "192.168.0.10" in
        Join.Site.there (Unix.ADDR_INET(server_addr.Unix.h_addr_list.(0),12345))
let ns = Join.Ns.of_site server
let sqr = (Join.Ns.lookup ns "square": int -> int)
let _ = Printf.printf "%d\n" (sqr 3)

如果两个程序都在同一台计算机上运行,​​那么这一切都很好。但是我的目标是将它们放在两个不同的机器中。因此,上述IP应该成为其他一些公共(public)IP。由于我只有一台机器来测试,因此我决定在该机器上运行这两个程序,并写出我的机器的公共(public)IP(而不是上面的192.168.0.10)。不幸的是,它不起作用,连接超时。

有任何想法吗?

[编辑]

有关该问题的更多详细信息

我上面编写的代码是我从JoCaml手册中摘取的一个示例,因为它是问题所在的我自己的代码的简化版本。我正在编写的程序旨在创建JoCaml运行时的P2P网络,这些网络均进行私有(private)计算,并依赖于存储在网络其他同级中的数据将其结果存储在本地。因此,我希望有一组对等体都运行与q.ml类似的东西,因为它们需要连接到其他计算机并从中获取所需的信息。

每个对等方都需要保留其对等方的列表。然后,您可以通过简单的方式向网络查询某些值。每个对等方将检查它是否知道该值:如果是,则返回该值;如果不是,则向其对等方询问(依此类推,以递归方式)。 P2P体系结构对于我的目的而言确实非常好。 (由于他的答案中提到的性能和可靠性问题,Gilles建议的集中式拓扑不适用于我的特定问题。)我介绍了一个特殊的引导对等体,所有代码都知道该引导对等体,任何新对等体都将首先连接到该引导对等体访问网络。一旦新的对等方通过引导对等方进行身份验证,它便应加入网络并自己成为一流的对等方(并且此后可能会忽略引导对等方)。这些对等体将在它们之间直接进行直接通信(1-1),因此,需要有一种方法可以使每对任意对等体在它们之间建立连接。另外,由于我希望具有适当凭据的任何人都可以加入该网络,而不论他们的网络技能如何,因此我无法提供一种解决方案,因为人们需要配置其路由器才能加入P2P网络。他们应该开箱即用地运行该软件。

我的要求是:
  • Internet上的对等点的P2P网络(因此,任意两个节点之间的1-1连接)
  • 对等设备可能位于不透明的路由器之后
  • 没有本地路由器配置
  • 首次连接并验证
  • 的特殊引导对等点

    如果不需要我们,我目前拥有的一切都很好。2。在这种P2P环境下,有什么建议可以解决最初的问题?

    (请注意,P2P框架只是达到目的的一种手段。是的,我想拥有一些运作良好的方法,但我无意为JoCaml开发最终的超通用P2P框架。我希望写一件简单的事情就可以完成工作。)

    最佳答案

    (我认为您的问题与IP网络拓扑有关,而与编程本身无关,但您需要了解此背景才能在JoCaml中进行编程。)

    很久以前,Internet上的每台计算机都有一个IP地址,如果您知道该计算机的IP地址,则可以与该计算机通信。 (路由器的每个接口(interface)只有一个IP地址,但这只是网络管理员需要考虑的问题。)啊,过去的简单起见。

    现在事情变得更加复杂了。 Intranet上的计算机通常具有仅在该Intranet上有效的地址,即所谓的private address。 192.168.0.10就是这样的私有(private)地址。您只能与该Intranet中具有私有(private)地址的计算机进行通讯。当计算机需要与外部建立连接时,network address translation (NAT)用于进行特定的连接。 NAT为Intranet计算机提供公用地址,但仅对特定连接有效。

    我怀疑您面临的网络拓扑如下所示:A是您的计算机,C是您最终要使用的另一台计算机,R是您的家庭或办公室路由器,1.2.3.4是您所谓的公共(public)IP您的计算机(实际上是网络)的:

    C [5.6.7.8] ←———→ [1.2.3.4] R [192.168.0.1] ←———→ [192.168.0.10] A
    

    在这种情况下,C无法使用192.168.0.10地址与A对话,因为该地址仅在Intranet上有意义。如果C完全可以与A对话,则它必须使用1.2.3.4,并且R必须配置为将寻址到1.2.3.4的数据包中继到A(在典型配置中,R仅在某些TCP或UDP端口上才这样做)。但是A无法使用1.2.3.4作为地址与自己通信:从内部传入,很可能仅到达R。

    这个问题(网络中的参与者没有全局可见的唯一地址)是可能的,但是理论上很烦人,而实际上却很烦人。据我所知,Jocaml的库使用IP地址和端口号来唯一且全局地标识分布式程序中的节点。 。

    考虑到现代网络拓扑结构的复杂性,通常可以将问题分为两个部分:使机器相互通信,以及实际运行分布式程序。第二部分是在JoCaml中进行编程时的工作。对于第一部分,ssh是首选工具。确定一台计算机或一个网络区域(Int​​ernet或Intranet)作为程序将运行的域,然后使用SSH隧道将该域之外的每台计算机连接到该域中的计算机。此方法不适用于所有用例:域外的两台计算机之间的通信将通过域,这可能是性能和可靠性问题。要做到这一点,您需要配置网络,以便每个参与者都有一个对其他参与者可见的地址(您可能会或可能不会这样做,具体取决于您被允许在网络上进行的操作)。所涉及的路由器);或为JoCaml实现非全局地址模型(这将很有趣且有用,但需要很多努力)。

    关于sockets - JoCaml : problems with remote connection,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5209350/

    10-10 03:19