gpt4 book ai didi

java - RMI:在特定网络地址和端口上创建服务器

转载 作者:行者123 更新时间:2023-11-30 07:14:52 31 4
gpt4 key购买 nike

我想在我以编程方式选择的端口和网络接口(interface)上创建 rmi 服务器(无需 jvm 设置)。例如我想要rmi服务器监听接口(interface)127.0.0.1和端口2525。我在网上查阅了资料,这就是我最终找到的解决方案。

class ServerSocketFactory implements RMIServerSocketFactory, Serializable {

public ServerSocket createServerSocket(int port) throws IOException
{
ServerSocket server = new ServerSocket(2525, 0, InetAddress.getByName("127.0.0.1"));
return server;
}
}

这就是我创建注册表的方式

registry = LocateRegistry.createRegistry(2525,null,new ServerSocketFactory());

但是,我遇到了异常(exception):

java.rmi.server.ExportException: Port already in use: 2525; nested exception is: 
java.net.BindException: Address already in use
at sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:341)

我不明白为什么如果我在 createRegistry 中使用 ServerSocketFactory 还有一个端口参数。我的错误是什么?

附注这不是 Remote method invocation port in use 的重复项因为它是关于选择网络接口(interface)而不是端口。

最佳答案

BindException 表示该端口已在使用中。因此,您运行此代码两次,或者有其他东西正在端口监听。

您不必指定端口号两次。只需使用作为 createServerSocket() 参数提供的端口号。它将是您导出时指定的端口号,或者零。

如果您使用此套接字工厂的多个实例,则需要在套接字工厂类中实现equals(),以便它为所有实例返回true这门课。

注意,RMIServerSocketFactory 实现不需要是可序列化。事实上,除了绑定(bind)到 127.0.0.1 之外,您根本不需要 RMIServerSocketFactory 实现类。不清楚您为什么要这样做,因为这意味着您要在同一主机内执行所有 RMI,这是非常徒劳的。

总而言之,您需要:

registry = LocateRegistry.createRegistry(2525);

myObject = new MyRemoteObject(2525);

// constructor
public MyRemoteObject(int port) throws RemoteException
{
super(port);
}

如果您需要远程对象(包括注册表)仅监听一个本地 IP 地址而不是所有本地 IP 地址,那么您就需要 RMIServerSocketFactory:

public class MyRMIServerSocketFactory implements RMIServerSocketFactory
{
private InetAddress address;

public MyRMIServerSocketFactory(InetAddress address)
{
this.address = address;
}

@Override
public ServerSocket createServerSocket(int port) throws IOException
{
return new ServerSocket(port, 0, address);
}

@Override
public boolean equals(Object that)
{
return that != null && this.getClass() == that.getClass() && this.address.equals((MyServerSocketFactory)that).address);
}
}

使用它:

Registry registry = LocateRegistry.createRegistry(2525, null, new MyServerSocketFactory(address));

public MyRemoteObject(int port, InetAddress address) throws RemoteException
{
super(port, null, new MyServerSocketFactory(address);
}

这个游戏的规则是,当且仅当以下情况时,从同一 JVM(可以包括注册表)导出的远程对象之间共享端口:

  1. 它们都不使用服务器套接字工厂,或者全部使用在 equals() 下相等的服务器套接字工厂
  2. 它们都使用相同的端口号,或者为零,或者不使用端口号,或者在导出的第一个对象之后全部使用零或不使用端口号(当它们共享第一个端口号时)。请注意,这意味着如果满足 (1),则默认情况下会发生端口共享。

关于java - RMI:在特定网络地址和端口上创建服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38585629/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com