如何创建一次只接受一个连接的rmi服务器?

时间:2011-06-18 02:42:24

标签: java rmi

我正在使用rmi java在java中编写客户端 - 服务器对。我希望服务器监听连接,当连接一个客户端时,服务器应拒绝任何其他尝试连接的客户端。

3 个答案:

答案 0 :(得分:2)

您需要使用http://download.oracle.com/javase/6/docs/api/java/rmi/registry/LocateRegistry.html#createRegistry%28int,%20java.rmi.server.RMIClientSocketFactory,%20java.rmi.server.RMIServerSocketFactory%29在代码中启动RMI注册表,并编写一个返回仅接受单个连接的ServerSocket的自定义RMIServerSocketFactory

编辑:使用LocateRegistry.createRegistryhttp://download.oracle.com/javase/1.5.0/docs/guide/rmi/hello/Server.java的mashup并加入一些额外的代码(注意我没有编译它,所以你需要自己解决任何编译错误;它旨在向您展示一般用法):

编辑2:修改它以纳入@ EJP的建议(更多细节参见this)。

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Server implements Hello {

    public Server() {}

    public String sayHello() {
    return "Hello, world!";
    }

    public static void main(String args[]) {

    try {
        Server obj = new Server();
        RMIClientSocketFactory csf = new RMIClientSocketFactory() {
            @Override
            public Socket createSocket(String host, int port) throws IOException {
                InetAddress addr = InetAddress.getByName(host);
                if (addr.equals(InetAddress.getLocalHost())) {
                    return new Socket(addr, port);
                } else {
                    throw new IOException("remote socket bind forbidden.");
                }
            }
        };
        RMIServerSocketFactory ssf = new RMIServerSocketFactory() {
            @Override
            public ServerSocket createServerSocket(int port) throws IOException {
                System.out.println("RMIServerSocketFactory().createServerSocket()");
                return new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
            }
        };
        Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0, csf, ssf);

        // Bind the remote object's stub in the registry
        Registry registry = LocateRegistry.createRegistry(uri.getPort(), csf, ssf);

        registry.bind("Hello", stub);

        System.err.println("Server ready");
    } catch (Exception e) {
        System.err.println("Server exception: " + e.toString());
        e.printStackTrace();
    }
    }
}

答案 1 :(得分:0)

一种简单的本土方法是通过一种方法传递所有内容,以跟踪请求线程的数量。如果正在进行请求线程,则可以抛出异常。否则,允许请求线程继续。

一些代码用于说明概念,但不一定是实现......

public class RequestHandler {

    private boolean activeRequest = false;


    public void handeRequest() throws Exception {
         synchronized(this) {
             if (activeRequest) {
                throw new Exception("Request in progress");
             }
             else {
                 activeRequest = true;
             }
         }

         // delegate to something else to perform the request logic


         synchronized(this) {
            activeRequest = false;
         }
    }

}

答案 2 :(得分:0)

您只需将远程方法声明为已同步即可。然后,一次只有一个客户可以输入它们。