RMI程序服务端运行正常但客户端执行失败,求代码修复方案
RMI程序问题修正方案
存在的问题
- 接口文件名与接口名不匹配:你创建的文件名为
ReceiverMessageInterface.java,但代码中公共接口的名称是ReceiveMessageInterface,Java强制要求公共类/接口的文件名必须和名称完全一致,否则会出现类找不到的错误。 - 客户端无入参校验:客户端直接运行时如果没有传入3个参数(服务端地址、端口、发送内容),会直接抛出数组越界异常。
- 缺少RMI安全配置:高版本JDK对RMI增加了安全限制,未配置安全策略和服务端主机名的情况下,会出现连接失败、类加载被拒绝的问题。
- 服务端未公开可访问的主机地址:默认情况下RMI会绑定回环地址,远程客户端访问时会无法连接。
修正后的完整代码
1. 接口文件(ReceiveMessageInterface.java,文件名必须和接口名一致)
package com.mycompany.dsa3; import java.rmi.Remote; import java.rmi.RemoteException; public interface ReceiveMessageInterface extends Remote { void receiveMessage(String x) throws RemoteException; }
2. 服务端文件(RmiServer.java)
package com.mycompany.dsa3; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import java.net.InetAddress; public class RmiServer extends UnicastRemoteObject implements ReceiveMessageInterface { Registry registry; public void receiveMessage(String x) throws RemoteException { System.out.println("收到客户端消息:" + x); } public RmiServer() throws RemoteException { try { // 配置RMI服务端对外暴露的IP地址 String serverIp = InetAddress.getLocalHost().getHostAddress(); System.setProperty("java.rmi.server.hostname", serverIp); int port = 3232; System.out.println("服务端启动,地址:" + serverIp + ",端口:" + port); // 创建注册中心并绑定服务 registry = LocateRegistry.createRegistry(port); registry.rebind("rmiServer", this); } catch (Exception e) { System.out.println("服务端初始化失败:" + e.getMessage()); e.printStackTrace(); } } public static void main(String args[]) { try { RmiServer server = new RmiServer(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } }
3. 客户端文件(RmiClient.java)
package com.mycompany.dsa3; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class RmiClient { public static void main(String args[]) { // 增加入参校验 if (args.length < 3) { System.out.println("参数错误,请按格式传入:java RmiClient 服务端地址 服务端端口 发送内容"); System.exit(1); } String serverAddress = args[0]; int serverPort = Integer.parseInt(args[1]); String text = args[2]; System.out.println("正在发送消息:" + text + " 到 " + serverAddress + ":" + serverPort); try { Registry registry = LocateRegistry.getRegistry(serverAddress, serverPort); ReceiveMessageInterface rmiServer = (ReceiveMessageInterface) registry.lookup("rmiServer"); // 调用远程方法 rmiServer.receiveMessage(text); System.out.println("消息发送成功"); } catch (RemoteException | NotBoundException e) { System.err.println("客户端运行错误:" + e.getMessage()); e.printStackTrace(); } } }
运行步骤
- 编译所有Java文件:
javac com/mycompany/dsa3/*.java
- 在项目根目录新建RMI安全策略文件
rmi.policy,内容如下:
grant { permission java.security.AllPermission; };
- 运行服务端:
java -Djava.security.policy=rmi.policy com.mycompany.dsa3.RmiServer
- 运行客户端(替换参数为你实际的服务端地址、端口、发送内容):
java -Djava.security.policy=rmi.policy com.mycompany.dsa3.RmiClient 192.168.1.10 3232 "这是测试消息"
内容的提问来源于stack exchange,提问作者YAChee
相关产品推荐
相关产品推荐

