如何打印我在CMD上没有开始的那个类的内容

时间:2011-12-22 11:18:29

标签: java rmi

这是一个与RMI有关的问题。我有4个.class文件接口,它的实现,一个名为server的类和一个名为client的类。

启动rmiregistry后,启动服务器,如:

import java.rmi.Naming;


public class Server {
  public static void main(String args[]) {
      try {
          to_Server_Impl toServer = new to_Server_Impl();
          Naming.rebind("Server", toServer);
      } catch(Exception exc) {
          System.out.println(exc);
        }
  }
}

然后我启动代码为的客户端:

import java.rmi.Naming;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;


 public class Client {
   public static void main(String args[]) {
       try {
            to_Server_Intf s_Intf = (to_Server_Intf)Naming.lookup("rmi://127.0.0.1/Server");
          do {  
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String message_to_send = null;
            System.out.println("===Enter your message===");
            message_to_send = br.readLine();
            // sending a message to the server
            String reply = s_Intf.send(message_to_send);
            System.out.println(reply);
          }while(true);
       }catch(Exception exc) {
           System.out.println(exc);
       }
   }
}

使用远程对象的引用,我调用该类的函数send,其代码如下:

import java.rmi.*;
import java.rmi.server.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class to_Server_Impl extends UnicastRemoteObject implements to_Server_Intf{
    public to_Server_Impl() throws Exception{ }

@Override
public String send(String str){ // this function receives the message from the Client.
    // this method indirectly replies,by calling reply and then returning the replies string
    String receivedString = str;        
    System.out.println(receivedString);
    System.out.println();
    String reply = reply();

    return reply;
}

@Override
public String reply() { // this function replies the Client
    String replyString = null;
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            replyString = br.readLine();
        }catch(Exception exc) {
            System.out.println(exc);
        }
    return replyString;
 }
}

当我将上述类的方法调用上述类的print语句时,请在“server”窗口中打印消息。这怎么可能?

客户端窗口:(客户端正在发送消息)

enter image description here

服务器窗口:(消息在服务器窗口上打印(调用被定向到类to_Server_Impl的函数)。如何?)

enter image description here

2 个答案:

答案 0 :(得分:2)

我不明白你的问题。在send方法(在服务器上,即客户端在服务器上远程调用它)中,您正在打印收到的消息。因此,它出现在服务器控制台中。

编辑:基本上这就是RMI的工作原理:

服务器应用程序发布一个接口,其中包含要调用的可用方法。在您的情况下,这是to_Server_Intf。服务器还具有接口的实现,即to_Server_Impl。服务器通过Naming.bind(或Naming.rebind)将远程对象发布到注册表。

客户端只知道服务器上的接口,但不了解实现。他们可以在注册表上进行查找,并使用Naming.lookup按名称查找远程对象。现在客户端有一个远程对象实例,可以在其上调用方法。此对象(客户端代码中的s_intf)实际上是服务器上存在的接口实现的本地代理。当客户端在此代理上调用方法时,该调用实际上被发送到服务器上的对象,这就是您在服务器控制台中看到该字符串的原因。

当客户端在本地存根上调用方法时实际发生的是,参数(如果有的话)被序列化并且创建了TCP套接字消息(或者任何底层实现),这些消息被发送到服务器收听传入的请求。在服务器端,接收消息,反序列化参数并从消息中识别正确的方法并调用。在方法返回后,再次将结果序列化,创建一条TCP消息,然后将其发送回客户端。

答案 1 :(得分:0)

这是一个远程对象。它在服务器上执行。它在服务器上打印输出。这就是RMI 的含义。如果它在客户端打印输出,则必须是本地对象而不是远程对象。