在使用Java将多个客户端连接到RMI服务器时,获取“ObjectID已在使用中”错误

时间:2015-03-04 14:03:53

标签: java multithreading client-server rmi

在我们的项目中,我们尝试将多个客户端连接到一台服务器。客户端使用RMI函数调用调用Button-CLick上RMI Server上定义的所有函数。服务器也是多线程的。在第一个客户端连接上,所有RMI服务器在其各自的端口上正常启动,但是当第二个客户端尝试连接时,将创建一个用于客户端的新线程,但由于端口已在使用中,因此未启动RMI服务器。这里它给出了“ObjID Already”使用错误。

我们要为客户提供File Uploading&amp ;;的功能。在不同的Swing Client表单上使用不同的按钮单击下载,最终在服务器端调用RMI函数。

请建议我们该怎么办?

有没有更好的方法来进行多客户端服务器端函数调用?

服务器端Begin.java代码

package sedas;
public class Begin implements Runnable {
protected static Socket clientsocket;
public static String directorypath = "C:\\BEProject\\";


public Begin(Socket sock) {
    Begin.clientsocket = sock;
}

public static void main(String args[]) throws Exception {
    ServerSocket ssock = new ServerSocket(15127);
    System.out.println("Listening");
    while (true) {
        Socket sock = ssock.accept();
        System.out.println("Connected to " + sock.getInetAddress());
        new Thread(new Begin(sock)).start();
    }
}

@Override
public void run() {
    try {
        RMILogIn rmilogin = new RMILogIn();

//Port for RMILogIn is 3230 defined in RMILogIn.java file
//Similarly for all others RMI files
        RMIRegistration rmiregister = new RMIRegistration();
        RMILogout rmilgout = new RMILogout();
        RMISendFiles rmiSend = new RMISendFiles();
        RMIShowFiles rmiSendfiles = new RMIShowFiles();
        RMIGetFiles newrmi = new RMIGetFiles();

    } catch (RemoteException ex) {
        Logger.getLogger(Begin.class.getName()).log(Level.SEVERE, null, ex);
    }

}
}

客户端连接代码

package sedas;

public class Sedaslogin extends javax.swing.JFrame {

OutputStream osuname = null;
private static Component frame;
public static InetAddress address;
public static Socket socket;

/**
 * Creates new form
 */
public Sedaslogin() {
    initComponents();
}                       
private void initComponents() {

    jDesktopPane1 = new javax.swing.JDesktopPane();
    jPanel1 = new javax.swing.JPanel();
    jLabel1 = new javax.swing.JLabel();
    jLabel2 = new javax.swing.JLabel();
    username = new javax.swing.JTextField();
    password = new javax.swing.JPasswordField();
    login = new javax.swing.JButton();
    signup = new javax.swing.JButton();
    jLabel3 = new javax.swing.JLabel();


private void signupActionPerformed(java.awt.event.ActionEvent evt) {                                       
    // TODO add your handling code here:
    this.setVisible(false);
    new Registration().setVisible(true);
}                                      

private void loginActionPerformed(java.awt.event.ActionEvent evt) {                                      
     try {

    LoginInterface RMILogin;
    Registry registry;
    String serverAddress = address.getHostAddress();
    String serverPort = "3230";
    //System.out.println("sending " + text + " to " + serverAddress + ":" + serverPort);
    try {

        registry = LocateRegistry.getRegistry(serverAddress, (new Integer(serverPort)));
        // look up the remote object
        RMILogin = (LoginInterface) (registry.lookup("RMILogIn"));
        // call the remote method
        osuname = socket.getOutputStream();
        DataOutputStream doucred = new DataOutputStream(osuname);
        doucred.writeUTF(username.getText());
        char[] pw = password.getPassword();
        String password = new String(pw);
        doucred.writeUTF(password);
        RMILogin.LogIn();


        //System.out.print(password);
        InputStream is = socket.getInputStream();
        DataInputStream status = new DataInputStream(is);
        String receivedstat = status.readUTF();
        if (receivedstat.equals("Successful")) {
            this.setVisible(false);
            new Choice().setVisible(true);
        } else if (receivedstat.equalsIgnoreCase("error")) {
            jLabel3.setText("Invalid Username/Password");
        }
    } catch (RemoteException | NotBoundException e) {
    }
   } catch (IOException ex) {
        Logger.getLogger(Sedaslogin.class.getName()).log(Level.SEVERE, null, ex);
    }
}
public static void main(String args[]) {
    try {
        // TODO add your handling code here:
        address = InetAddress.getByName("hp-hp");
        //System.out.println(address.getHostAddress());
        socket = new Socket(address.getHostAddress(), 15127);
        JOptionPane.showMessageDialog(frame, "Connection Accepted by Server!");
    } catch (IOException ex) {
        Logger.getLogger(ClientUpload.class.getName()).log(Level.SEVERE, null, ex);
        JOptionPane.showMessageDialog(frame, "Connection Rejected by Server!");
        System.exit(1);
    }

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new Sedaslogin().setVisible(true);
        }
    });
}

P.S。:假设所有导入都已完成且Client有Swing GUI。

1 个答案:

答案 0 :(得分:1)

您尝试在同一JVM中创建多个注册表。你不能,除非你为每个端口使用不同的端口,并且没有意义,并且你首先不需要它。

你从头到尾都做错了。

  • 摆脱侦听套接字,接受和线程。
  • 创建并注册一组远程对象。
  • 重新定义远程接口以获取参数,而不是将其写入套接字。
  • 让客户端查找远程对象,并使用参数调用它们,同时删除客户端套接字。

RMI比你想象的要强大得多。