2009-07-22 7 views
1

클라이언트 - 서버 기반 응용 프로그램을위한 통신 프로토콜을 구현하고 싶지 않았기 때문에 두 구성 요소 사이의 정보 교환을 위해 양쪽에 RMI 클라이언트와 RMI 서버를 구현했습니다.RMI 환경을 "실제"네트워크에서 사용할 수 있도록 구성하려면 어떻게해야합니까?

동일한 컴퓨터에서 두 구성 요소를 시작하여 응용 프로그램을 사용하려고하면 모든 것이 정상적으로 작동합니다. 하지만 두 개의 다른 컴퓨터 (Windows 7 RC 환경에서 방화벽이 작동하지 않고 기본 Ubuntu 9.04 환경의 가상 컴퓨터 내에서 쿠분투 9.04)로 구성 요소를 분할하면 RMI 클라이언트가 다음과 같은 방법을 실행할 수없는 것처럼 보입니다. 서버 측에서 정의됩니다. (모든 함수 호출은 RMI 예외를 발생시킵니다.)

현재 데이터 교환에 사용해야하는 네트워크 인터페이스의 양쪽에 "java.rmi.server.hostname"시스템 속성 만 설정하고 기본값을 등록합니다 rmi 데몬 (?) rmid와 통신하기위한 포트.

누군가가 잘못 될 수있는 아이디어가 있습니까? 내 응용 프로그램 내에서 RMI 기능을 사용하려면 "java.rmi.server.codebase"(http://java.sun.com/j2se/1.4.2/docs/guide/rmi/javarmiproperties.html)와 같은 다른 매개 변수를 설정해야합니까?

편집 :

내 클라이언트는 다음과 같은 두 가지 방법을 사용하여 초기화 된 서버 구성 요소의 RMI 서버에 연결을 시도 초기화 단계에서 : 좋아, 여기 당신을 위해 몇 가지 추가 정보가

private void initialize() 
{ 
    // set ip address of rmi server 
    System.setProperty("java.rmi.server.hostname", ipAddress); 

    // try to register rmi server 
    try 
    { 
     LocateRegistry.createRegistry(Registry.REGISTRY_PORT); 
    } 
    catch (Exception e) 
    { 
     // ignore 
    } 
} 

public void start() 
{ 
    System.out.print("starting master control RMI server ..."); 

    try 
    { 
     Naming.rebind("MasterControl", this); 
    } 
    catch (Exception e) 
    { 
     System.out.println("error: could not initialize master control RMI server"); 
     System.exit(1); 
    } 

    // set running flag 
    isRunning = true; 

    System.out.println(" done"); 
} 

"ipAddress"는 서버 구성 요소의 네트워크 인터페이스의 IP 주소입니다.

연결을 설정하기 위해 클라이언트 구성 요소에 의해 사용되는 방법은 다음과 같습니다

public void connect() 
{ 
    // build connection url 
    String url = "rmi://" + masterControlIpAddress + "/MasterControl"; 

    System.out.println(url); 

    System.out.print("connecting to master control ..."); 

    // try to connect to master control server 
    while (connection == null) 
    { 
     try 
     { 
      connection = (MasterControlInterface) Naming.lookup(url); 
      id = connection.register(localIpAddress); 
     } 
     catch (Exception e) 
     { 
      // ignore 
     } 

     if (connection == null) 
     { 
      try 
      { 
       Thread.sleep(100); 
      } 
      catch (InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 

    System.out.println(" done"); 
} 

내 클라이언트가 서버에 연결 등록 함수를 호출 볼 수 있듯이 :

@Override 
public int register(String ipAddress) throws RemoteException 
{ 
    // add connection to registrationHandler 
    masterControl.registrationHandler.addConnection(ipAddress); 

    // log 
    int connectionCount = masterControl.registrationHandler.getConnectionCount(); 
    System.out.println("slave control (" + ipAddress + ") instance has been registered at the master control server under the following id: " + connectionCount); 

    return connectionCount; 
} 

실제 네트워크 연결을 사용하여 프로그램을 실행하면 "slave control ..."텍스트가 서버 측에 표시되지 않습니다. 따라서 함수가 실제로 클라이언트 구성 요소에 의해 호출되는지 확실하지 않습니다.

클라이언트 컴포넌트는 intialized된다

후 그것을 사용하여 다음과 같은 메소드를 호출하여 서버 구성 요소에게 통지하려고 서버 RMI 연결이다 :

public void sendInitializationDone() 
{ 
    try 
    { 
     connection.initializationDone(); 
    } 
    catch (RemoteException e) 
    { 
     System.out.println("error: could not send 'initializationDone' message to master control"); 
     System.out.println(e); 
     System.exit(1); 
    } 
} 

서버 측에 플래그를 설정하기 위해.

오류가 클라이언트 측에서이 함수 내부 occures :

java.rmi.ConnectException : 연결이 127.0.1.1 호스트 거부; 중첩 예외는 java.net.ConnectException : Connection refused.

나는, 내가 Windows 방화벽 카스퍼 스키 인터넷 시큐리티의 보호 mechanismn을 사용할

물론

@nos 호스트가 여기에 127.0.1.1 왜 아무 생각이 ... 없습니다. 쿠분투에는 방화벽이 실행되고 있다고 생각하지 않습니다.generell에서는 scp를 사용하여 이미 내 프로그램을 다른 컴퓨터에 복사했기 때문에 연결을 설정할 수 있습니다.

Edit2가 :

Mhhh, 그것을 작동하는 것 같다 시스템의 IP 주소로 컴퓨터를 의미하지만 않는 이유를 정말 이해가 안 돼요/etc/hosts 파일의 항목을 설정 한 후 ... 각 서버에서 JDK의 다른 버전을 사용

BR,

마르쿠스

+2

RMI 예외는보기 좋을 것입니다. –

+0

우선 무엇이 실패하는지 알려주는 예외를 붙여 넣으십시오. 기본 네트워킹이 호스트와 가상 컴퓨터 사이에서 작동하는지 확인했다고 가정합니다. kubuntu와 windows 컴퓨터가 어떤 종류의 방화벽으로도 설정되어 있지 않은지 확인하십시오. – nos

+0

자세한 정보가 필요하다고 생각합니다. –

답변

5

당신은 형태

machinename privateip 

예를 들어,의 항목을 포함하는 기계의 hosts file에 항목을 추가 할 필요가

virtualmachine 192.168.1.16 

은 '다시 내게 전화'주소로 localhost 호스트 이름을 보내지 RMI를 방지 할 수 있습니다.

이 방법을 테스트하려면 변경하기 전후에 다음 코드를 실행하십시오.

System.out.println(java.net.InetAddress.getLocalHost()); 

변경 전 로컬 주소와 변경 후 로컬 주소가 출력되어야합니다.

+0

Mhhh, 당신 말이 맞아요. 이 항목을 설정하면 모든 것이 정상적으로 작동하지만 이것이 유일한 해결책 일 수 있다고 생각합니다. "java.rmi.server.hostname"속성을 사용하여 '콜백'주소를 설정할 수없는 이유는 무엇입니까? – Markus

+1

아니, 잘 모르겠다. RMI를 프로덕션 환경에서 사용하고 나면, 대신 다른 것을 사용하게 될 것입니다. 구성이 올바르다는 것은 다소 어려운 일입니다. 그리고 오래 된 RMI 스텁 규칙 ;-) –

+0

서버 PC에서이 작업을 수행해야합니까? 나는 이미 호스트 파일에'127.0.0.1 localhost' 줄의 주석 처리를 해제했다. 나는 그것을 제거해야 했습니까? –

-2

이 문제의 원인이 될 수 있습니다.

java -version 명령을 사용하여 동일한 버전의 jre를 사용하고 있는지 확인하십시오.

+0

아니요, 양쪽에 동일한 jre 패키지가 설치되어 있습니다 (sun-java6-jre) : Java 버전 "1.6.0_14" Java (TM) SE 런타임 환경 (빌드 1.6.0_14-b08) Java HotSpot TM) 클라이언트 VM (빌드 14.0-b16, 혼합 모드, 공유) – Markus

+0

이 대답은 난센스입니다. 다른 버전의 JDK를 사용해도 연결 거부가 발생하지 않습니다. – EJP

관련 문제