3

クライアントがサーバーにリモート呼び出しを行い、サーバーが文字列を返す単純なjavarmiプログラムを試しました。LAN経由で接続された2台のコンピューターで完全に機能しました。LAN経由でサーバーに接続されていないが、サーバーとクライアントの両方がインターネットに接続されているクライアントによるリモート呼び出しを実装するにはどうすればよいですか?Client.javaの「localhost」をサーバーのIPアドレスに変更して、次の簡単なコードを試しました。動作しませんでした。そのようなリモートコールを行うには何が必要ですか?

//リモートインターフェース->MyInterface.java

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface MyInterface extends Remote
{
    public String SaySomething() throws RemoteException;
}

//Client.java

import java.rmi.*;
import java.rmi.registry.*;

public class Client
{
    public static void main(String []args)
    {
        System.setProperty( "java.security.policy", "client.policy" );
        if (System.getSecurityManager() == null)
                    System.setSecurityManager(new RMISecurityManager());
        try {
                        String name = "MyInterface";
                        Registry registry = LocateRegistry.getRegistry("localhost",4501);
                        MyInterface mi = (MyInterface) registry.lookup(name);
            System.out.println(mi.SaySomething());
                } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//Server.java

import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.UnicastRemoteObject;

public class Server implements MyInterface
{
    public Server()
    {
        super();
    }
    public String SaySomething()
    {
        return "Server Speaking";
    }
    public static void main(String []args)
    {
        System.setProperty( "java.security.policy", "server.policy" );
        if(System.getSecurityManager() == null)
           System.setSecurityManager(new RMISecurityManager());
            try {
                        String name = "MyInterface";
                        MyInterface mi = new Server();
                        MyInterface stub =(MyInterface) UnicastRemoteObject.exportObject(mi,4501);
                        Registry registry = LocateRegistry.createRegistry(4501);
                        registry.rebind(name, stub);
                        System.out.println("Server bound");
            } catch (Exception e) {
            System.out.println("oops");
                }
    }
}

次の例外が発生します。 java.security.AccessControlException:java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)のjava.security.AccessController.checkPermissionでアクセスが拒否されました( "java.net.SocketPermission" "xxxx:4501" "connect、resolve") (AccessController.java:555)at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)at java.lang.SecurityManager.checkConnect(SecurityManager.java:1051)at java.net.Socket.connect(Socket.java: 574)java.net.Socket.connect(Socket.java:528)at java.net.Socket。(Socket.java:425)at java.net.Socket。(Socket.java:208)atsun.rmi。 sun.rmi.transport.proxy.RMIMasterSocketFactoryのtransport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)。createSocket(RMIMasterSocketFactory.java:146)at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)at sun.rmi .transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:340)at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)at Client.main (Client.java:14)java:14)java:14)

4

2 に答える 2

0

コードベース機能を使用していない限り、RMI 用のセキュリティ マネージャーは必要ありません。それを除く。

于 2013-07-10T01:12:28.010 に答える
-1

おそらくアクセスを確認する必要があります。

サーバーが自宅の PC である場合は、ルーターが着信接続を許可していることを確認する必要があります (既定ではブロックされています)。

サーバーがオフィス PC の場合、ファイアウォールによってブロックされている可能性があります。

于 2012-10-15T14:25:13.173 に答える