【问题标题】:knowing the port number during RMI在 RMI 期间知道端口号
【发布时间】:2012-01-25 09:25:57
【问题描述】:

有没有办法在RMI期间同时知道客户端和服务器的端口号?

在RMI期间向客户端返回结果时,下一次客户端请求结果时,客户端和服务器之间的会话是否会与上次相同,当服务器在返回第一个结果后一直在运行时还是创建了一个新端口?

例如:

// call to a remote method add
     addServerIntf.add(d1,d2)
// after this call i get the added result

// again call the add method by again starting the client
    addServerIntf.add(d1,d2)
// I get the result back as usual

在两次不同的调用中,客户端和服务器的端口号是否保持不变?

我的客户端程序在输入类似 java AddClient localhost 100 200 之类的命令后退出服务器上的方法返回300,客户端退出。下次我用 java AddClient localhost 19 100 再次启动我的客户端。现在请求将从与之前发送的相同端口发送,服务器会在同一端口接收请求吗?或者情况和我刚才写的不一样?

【问题讨论】:

  • 我觉得你的问题不是很清楚。如果您将远程对象绑定到某个端口,它将在那里可用并且不会移动到其他端口。您能否展示一些表明您的问题或澄清您的问题的代码?
  • 服务器端口当然​​不会改变。 OP正在谈论客户端的端口。所以问题是多个 RMI 调用是否建立到服务器的新连接(导致不同的客户端端口)。
  • 我认为您误解了套接字的一般工作方式。一旦建立了端点,端口就变得无关紧要了。
  • @Chris Dennett 告诉你,我的客户端程序在输入java AddClient localhost 100 200 之类的命令后退出,服务器上的方法返回300,客户端退出。下次我用java AddClient localhost 19 100 再次启动我的客户。现在请求将从与之前发送的相同端口发送,服务器是否会在同一端口上接收请求?还是情况和我刚才写的不一样?
  • 由于程序退出,我怀疑rmi客户端套接字也关闭了。然后,对您的程序的第二次调用将创建一个新的客户端套接字,它不能保证再次使用相同的端口,因为这是由操作系统控制的。但是我不知道如何获取客户端套接字实例以简单地输出端口。

标签: java rmi port-number


【解决方案1】:

有没有办法知道客户端和客户端的端口号 RMI 期间的服务器?

如果我没有误解,我认为在 RMI 会话期间无法知道端口号。

如果您的端口号与默认 RMI 注册服务器 1099 端口不同,则必须在 Server 类和 Client 类上设置它,因为正如 Oracle RMI page 报告的那样:

如果注册表将在 1099 以外的端口上运行,您需要 在对 LocateRegistry.getRegistry 的调用中指定端口号 在服务器和客户端类中。例如,如果注册表是 在本例中,在端口 2001 上运行,调用 getRegistry 服务器将是:

Registry registry = LocateRegistry.getRegistry(2001);

和:

此客户端首先通过调用 指定主机名的静态 LocateRegistry.getRegistry 方法 在命令行上。如果未指定主机名,则 null 用作 指示应使用本地主机地址的主机名。

那么,我的结论是,你无法通过方法知道 RMI 会话的端口号(你可以查看 RMI API 了解详细信息),除非你必须设置它,如果它不同于默认 RMI 注册服务器 1099 端口,因为您必须在 RMI 会话开始时知道它。

想一想:如何获得这个端口号?联系服务器还是客户端?例如,如果您请求位于特定服务器中的页面,该页面正在侦听端口 81(而不是默认的 80 端口),您需要提前提供端口号以连接到此特定服务器,并联系它,例如: http://192.168.1.1:81。然后,在 RMI 会话期间,您必须提前知道 RMI 注册端口。

查看page了解详情。

在 RMI 期间向客户端返回结果时,下一次 客户端请求结果,客户端与 服务器与以前的端口相同,当服务器已经 在返回第一个结果或创建新端口后运行?

当结果返回给客户端时,Client和Server之间的会话应该共享在同一个RMI注册端口上,否则,如果客户端设置的RMI注册端口与Server RMI注册端口不同(如果我没忘记),代码会抛出一个RemoteException,当RMI进程发生故障时会发生这种情况。

更新

现在我看到了您更新的问题。

在 2 个不同的调用中,客户端和服务器的端口号 保持不变?

它应该是相同的 RMI 注册服务器端口。当您的程序在第一次调用后退出时,程序会关闭套接字连接。下次启动程序时,RMI 注册表端口应该相同。否则,您的程序应该抛出异常,或者,当您将参数传递给程序时,您会得到意想不到的结果。如果我理解,您的客户端程序只是在服务器上调用 sum 方法。在第一个结果之后,下次启动程序时,您会得到不同的结果吗?如果不是,我认为RMI注册端口是一样的。

【讨论】:

  • 版主说明: 这个答案下的cmets无非是争论谁的答案是正确的,已经被清除了。请保持 cmets 建设性和主题,也请明智地投票。
  • “客户端和服务器之间的对话应该在同一个 RMI 注册端口上共享”不正确。它可以在某些条件下在注册表端口上共享。
【解决方案2】:

有没有办法知道客户端和服务器的端口号?

没有。您无法提前知道客户端端口号,因为它是在连接时动态分配的,并且服务器 IP:port 嵌入在您无法获取的存根中。为什么你需要知道?这些信息对你没有多大好处:你不能使用它。

在 RMI 期间向客户端返回结果时,下一次 客户端请求结果,客户端与 服务器与以前的端口相同,当服务器已经 在返回第一个结果或创建新端口后运行?

要么:

  • 客户端连接被重用,具有相同的端口号,或者
  • 在客户端创建一个可能带有新本地端口的新连接。

无法判断是哪个。服务器端口保持不变。

在 2 个不同的调用中,客户端和服务器的端口号 保持不变?

见上文。

我的客户端程序在输入java AddClient localhost 100 200 之类的命令后退出。服务端方法返回300,客户端退出。下次我用java AddClient localhost 19 100 再次启动我的客户。现在将从与之前发送的相同端口发送请求

可能不会。

服务器会在同一个端口接收请求吗?

没有看到你的服务器代码就不可能说。如果您将其导出到常量端口,则它会导出到常量端口。如果不是,则不是。真是重言式。

或者情况和我刚才写的不一样?

我不明白这个问题。

【讨论】:

  • @downvoter 请解释一下。无法解释的投票对任何人都没有任何好处:不是海报、OP 或社区。如果您认为以上有错误,请指出。
  • 您是否愿意解释一下服务器 IP:port 嵌入在您无法访问的存根中... !我认为LocateRegistry.getRegstry(int port_number); 已经允许客户端了解服务器端口号和/或 IP ..
  • @Am_I_Helpful LocateRegistry.getRegistry() 返回的存根是 Registry 存根;它仍然是一个存根,对应用程序是不透明的;它包含您作为参数提供给它的端口号,您已经知道了。这不是这个问题的解决方案。注意不回应评论的反对意见不是 SO 应该如何工作 IMO。
  • @EJB "IP:port 嵌入在您无法访问的存根中。" -- 如果客户端在查找后打印接收到的远程对象,则服务器端 ip 和端口将显示在日志中。有时有助于分析应用程序之间的网络数据包捕获。
  • @Nrj OP 要求提供一种方法, 但没有。
【解决方案3】:

了解您的 TCP/IP:客户端通过特定端口连接到服务器。客户端端口号是随机的(或者应该是出于安全原因),服务器端口号是已知的(否则,客户端首先无法连接)。

然后 TCP/IP 协议将建立连接。服务器将为连接创建一个处理程序,而 TCP/IP 将为这个连接分配一个新的随机端口。服务器端的端口号不会改变。由于服务器可以使用客户端的IP+端口作为区分不同“会话”的关键,因此任意数量的客户端都可以连接到同一个服务器端口。

这意味着:在 RMI 框架初始化后,客户端和服务器都将通过一对端口相互通信,只要连接存在,该端口就不会改变。

如果连接因某种原因被切断,则可以建立新的连接,但这可能会在客户端的双方上获得一个新的端口号s

我的客户端程序退出

这意味着连接被切断。当您再次启动客户端时,会创建一个新的客户端端口。它很可能(概率为 65534:65535,大约为 1)将是一个新的端口号。

如果您在两分钟内再次启动客户端,则端口号s 必须不同,因为旧端口s are 保持活动状态两分钟以确保"remote TCP received the acknowledgment of its connection termination request" (如果您运行netstat,您将看到这些状态为TIME_WAIT)。

【讨论】:

  • 完全不正确。 accept() 创建一个新的套接字,监听套接字的 IP:port 作为本地地址,客户端的 IP:port 作为目标地址。
  • EJP:完全不正确。当新套接字阻塞侦听端口时,您认为新客户端如何连接?即使我把这个细节弄错了,其余的答案仍然是正确的。
  • 在您重申此错误之前,请阅读 TCP RFC 或检查“netstat”的输出,并且不要对您被误导的主题的正确答案投反对票。您的整个答案包含这个错误的变体:没有“其余部分”“仍然是正确的”。
  • 使用来自 Wikipedia 和 RFC 的信息改进了我的答案。我想我把它和 FTP 混在一起了,它确实为数据连接打开了新的端口。 PS:说“完全不正确”并不是试图纠正我的好方法。这让我很生气。
  • 我看不出 FTP(一种应用程序协议)与 RMI(另一种应用程序协议)或 TCP(一种会话协议)有什么关系。 PS:正确的 cmets 相互矛盾,正确的答案被否决,也有点令人恼火;-)
猜你喜欢
  • 2012-11-16
  • 1970-01-01
  • 2020-09-20
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
相关资源
最近更新 更多