并行/分布式计算的新手,以及我正在尝试编写的客户端 - 服务器程序的问题。应该发生的是服务器从客户端接收一个整数并将所有数字的总和发回去(例如,用户输入5,服务器计算1 + 2 + 3 + 4 + 5,服务器返回15)。我还在努力解决这个问题,所以我在客户端对输入进行了硬编码。
这就是我在服务器端所拥有的:
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.net.*;
import java.util.*;
public class Server {
public static void main(String[]args) {
try{
int port = 16790;
String host = "localhost";
CalculateSumServerImpl export = new CalculateSumServerImpl();
LocateRegistry.createRegistry(port);
String registryURL = "rmi://" + host + ":" + port + "/sum";
Naming.rebind(registryURL, export);
System.out.println("Server ready");
} catch (Exception e) {
e.printStackTrace();
}
} }
//to calculate the sum
import java.rmi.*;
import java.rmi.server.*;
public class CalculateSumServerImpl extends UnicastRemoteObject implements CalServerInterface {
public int n; //value entered
public int sum; //sum
protected CalculateSumServerImpl() throws RemoteException {
super();
}
@Override
public int calculateSum(int n) throws RemoteException {
n = (n*(n+1))/2; //sum of 1 + 2 + 3 + .. + n
sum = n;
return sum;
} }
//interface
import java.rmi.Remote;
public interface CalServerInterface extends Remote {
public int calculateSum(int n ) throws java.rmi.RemoteException;
}
在客户端:
import java.rmi.*;
import java.util.PropertyPermission;
public class Client {
public static void main(String[]args) {
System.setSecurityManager(new java.rmi.RMISecurityManager());
System.setProperty("java.net.preferIPv4Stack" , "true");
try {
int port = 16790;
String host = "localhost";
String registryURL = "rmi://" + host + ":" + port + "/sum";
Project4ServerInterface obj = (Project4ServerInterface)Naming.lookup(registryURL);
System.out.println("Lookup completed.");
int output = obj.calculateSum(3);
System.out.println("Sum is: " + output);
} catch (Exception e) {
e.printStackTrace();
}
System.setProperty("java.net.preferIPv4Stack","true");
} }
我也在客户端实现了接口。
我在客户端获得的错误是:
线程“main”中的异常java.security.AccessControlException:access denied(“java.util.PropertyPermission”“java.net.preferIPv4Stack”“write”) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) 在java.security.AccessController.checkPermission(AccessController.java:884) 在java.lang.SecurityManager.checkPermission(SecurityManager.java:549) 在java.lang.System.setProperty(System.java:792) 在project04client.Client.main(Client.java:10)
错误指向此代码的行:
System.setProperty("java.net.preferIPv4Stack" , "true");
任何人都有遇到此错误的经验吗?
谢谢!
答案 0 :(得分:2)
问题是您已为整个(客户端)应用程序设置了一个安全管理器,它不允许您修改系统属性。
简单的解决方法是在设置RMI安全管理器之前设置需要设置的系统属性。
或者,您可以完全摆脱System.setSecurityManager(...)
电话。如果您希望客户端能够从RMI服务下载类,您(可能)只需要它。
我尝试在安全管理器之前设置系统属性并获得
AccessControlException
,拒绝套接字权限。
这没有多大意义。如果此时有安全管理员,您只能获得AccessControlException
。不应该......除非这是在Web浏览器中启动的applet代码或类似代码。另外,我不知道为什么拒绝设置属性的调用,说你没有套接字权限。
当我完全取出安全管理器时,我得到一个指向该接口的UnmarshalException。
您还需要将要解组的对象的类/接口添加到客户端类路径中。
实际上,我刚注意到RMISecurityManager
的{{3}}说:
“
RMISecurityManager
实施与SecurityManager
实施的策略相同的策略。 RMI应用程序应使用SecurityManager
类或其他适当的SecurityManager
实现而不是此类。强>“