当关闭服务器组件时,我遇到了一些麻烦,并希望得到一些帮助。
我的服务器代码如下所示,它有一个关闭服务器的方法
服务器
private final String address = "127.0.0.1";
private Registry registry;
private int port = 6789;
public RmiServer() throws RemoteException {
try {
registry = LocateRegistry.createRegistry(port);
registry.rebind("rmiServer", this);
} catch (RemoteException e) {
logger.error("Unable to start the server. Exiting the application.", e);
System.exit(-1);
}
}
public void shutDownServer() throws RemoteException {
int succesful = 0;
try {
registry.unbind("rmiServer");
UnicastRemoteObject.unexportObject(this, true);
Thread.sleep(1000);
} catch (NotBoundException e) {
logger.error("Error shutting down the server - could not unbind the registry", e);
succesful = -1;
} catch (InterruptedException e) {
logger.info("Unable to sleep when shutting down the server", e);
succesful = -1;
}
catch (AccessException e) {
logger.info("Access Exception", e);
succesful = -1;
}
catch (UnmarshalException e) {
System.out.println(e.detail.getMessage());
logger.info("UnMarshall Exception", e);
succesful = -1;
}
catch (RemoteException e) {
System.out.println(e.detail.getMessage());
logger.info("Remote Exception", e);
succesful = -1;
}
logger.info("server shut down gracefully");
System.exit(succesful);
}我的客户端连接良好,没有问题,所以为了关闭,我创建了一个新的应用程序,复制了客户机代码来连接,然后调用服务器上的close方法。
关机
公共类关闭{
private String serverAddress = "127.0.0.1";
private String serverPort = "6789";
private ReceiveMessageInterface rmiServer;
private Registry registry;
public Shutdown(){
try {
registry = LocateRegistry.getRegistry(serverAddress, (new Integer(serverPort)).intValue());
rmiServer = (ReceiveMessageInterface) (registry.lookup("rmiServer"));
logger.info("Client started correctly");
rmiServer.shutDownServer();
System.exit(0);
}
catch (UnmarshalException e ){
logger.error("Unmarshall exception. Exiting application", e);
System.exit(-1);
}
catch (RemoteException e) {
logger.error("Remote object exception occured when connecting to server. Exiting application", e);
System.exit(-1);
} catch (NotBoundException e) {
logger.error("Not Bound Exception occured when connecting to server. Exiting application", e);
System.exit(-1);
}
}无论我尝试什么,我都会得到以下的例外;
ERROR com.rmi.client.RMIClient - Unmarshall exception. Exiting application
java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is:
java.net.SocketException: Connection reset
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy0.shutDownServer(Unknown Source)
at com.rmi.shutdown.Shutdown.<init>(Shutdown.java:31)
at com.rmi.shutdown.Shutdown.main(Shutdown.java:52)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at java.io.DataInputStream.readByte(Unknown Source)
... 7 more我相信这可能是因为客户端没有正确断开连接,只是被“切断”,但我不确定如何断开服务器端的连接?
请有人指点一下。
谢谢
发布于 2013-08-12 04:35:49
= true不会中止正在进行的调用。一般来说,它会让进程调用运行到完成。您的shutDownServer方法几乎是正确的,因为它取消注册远程引用并取消导出它。不过,它接下来要做的事情不起作用。首先,它会睡上一秒钟。这将使调用保持在进行中,并使客户端等待回复。然后关闭代码退出服务器JVM,而不从远程调用返回。这关闭了客户端的连接,而它仍在等待回复。这就是客户端获得连接重置异常的原因。
要彻底关闭,请注销远程对象,用force = true (正如您所做的那样)取消导出它,然后简单地返回。这将向客户端发送一个回复,让其远程调用完成,然后退出。回到服务器上,在上一次正在进行的调用完成后,如果没有其他对象导出,并且如果没有其他任何东西使JVM保持在周围(例如非守护进程线程),JVM将退出。您需要让RMI完成其服务器端处理,而不是调用System.exit()。
发布于 2013-04-25 22:36:57
系统正按照你说的做。您让它自行取消导出,并将“force”参数设置为true,该参数将中止正在进行的调用,因此它退出了自身,并中止了正在进行的调用。忽略它,或者如果您坚持要对关机客户端进行干净的响应,那么让服务器为非导出操作启动一个新线程,延迟很短,这样关闭调用就可以返回给客户机。
https://stackoverflow.com/questions/16194175
复制相似问题