Java RMI错误:连接重置
我已经编写了三个rmi服务器,它们使用UDP单播相互发送数据。每次在服务器的特定实例上执行方法时,启动的服务器都会向其他服务器发送请求,这些服务器会响应在该服务器的特定实例上执行的方法的结果。我已经用线程实现了它们。该方法第一次执行,但当我再次执行时,会出现以下错误:Java RMI错误:连接重置,java,rmi,Java,Rmi,我已经编写了三个rmi服务器,它们使用UDP单播相互发送数据。每次在服务器的特定实例上执行方法时,启动的服务器都会向其他服务器发送请求,这些服务器会响应在该服务器的特定实例上执行的方法的结果。我已经用线程实现了它们。该方法第一次执行,但当我再次执行时,会出现以下错误: java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: java.net.SocketExce
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 com.sun.proxy.$Proxy0.getNonReturners(Unknown Source)
at drms.org.client.DRMSClient.main(DRMSClient.java:379)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
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)
... 6 more
getNonReturners-为udp通信创建线程的方法
请求数据:向其他服务器发送请求消息
响应数据:向请求响应消息的服务器发送响应消息
服务器端代码:
public class DRMSServer implements DRMSInterface, Serializable {
final static int _concordiaPortNumber = 1098;
final static int _mcgillPortNumber = 222;
final static int _dawsonPortNumber = 223;
/**
* Description: Sends UDP request from invoked Server to the other servers
*
* @param: Port Number
* @param: Data
*/
public String requestData(final int portNumber, final String data) {
StringBuilder sb = new StringBuilder();
try {
final DatagramSocket clientSocket = new DatagramSocket();
final byte[] receiveData = new byte[1024000];
final DatagramPacket receivePacket = new DatagramPacket(
receiveData, receiveData.length);
byte[] sendData = new byte[1024000];
sendData = data.getBytes();
System.out.print("Ready to send data ");
sb.append("Ready to send data ");
sb.append("\n");
final DatagramPacket sendPacket = new DatagramPacket(sendData,
sendData.length, IPAddress, portNumber);
clientSocket.send(sendPacket);
clientSocket.setSoTimeout(10000);
try {
clientSocket.receive(receivePacket);
final String _result = new String(receivePacket.getData());
final InetAddress returnIPAddress = receivePacket.getAddress();
final int port = receivePacket.getPort();
System.out.println("From server at: " + returnIPAddress + ":"
+ port);
sb.append("From server at: " + returnIPAddress + ":" + port);
sb.append("\n");
System.out.println("Message: " + _result);
sb.append("Message: " + _result);
}
catch (final SocketTimeoutException ste) {
System.out.println("Timeout Occurred: Packet assumed lost");
}
// clientSocket.close();
}
catch (final SocketException e) {
e.printStackTrace();
}
catch (final IOException e) {
e.printStackTrace();
}
return sb.toString();
}
/**
* Description: Returns the administrator with the list of defaulter who
* have a book past their loan date. Based on the UDP request from the
* invoked server it sends the UDP response.
*
* @param: Port Number
*/
public String responseData(final int portNumber) throws NotBoundException {
String _result = null;
try {
@SuppressWarnings("resource")
final DatagramSocket serverSocket = new DatagramSocket(portNumber,
IPAddress);
final DRMSInterface _concordiaServer = (DRMSInterface) Naming
.lookup("rmi://localhost:1098/concordia");
final DRMSInterface _mcgillServer = (DRMSInterface) Naming
.lookup("rmi://localhost:222/mcgill");
final DRMSInterface _dawsonServer = (DRMSInterface) Naming
.lookup("rmi://localhost:223/dawson");
byte[] receiveData = new byte[1024000];
byte[] sendData = new byte[1024000];
String regex = "(?<=[\\w&&\\D])(?=\\d)";
while (true) {
receiveData = new byte[1024000];
final DatagramPacket receivePacket = new DatagramPacket(
receiveData, receiveData.length);
System.out.println("Waiting for datagram packet");
serverSocket.receive(receivePacket);
final String _request = new String(receivePacket.getData());
System.out.println(_request);
String array[] = _request.split(regex);
String _educationalInstitution = array[0];
System.out.println(_educationalInstitution);
int numDays = Integer.parseInt(array[1].trim());
System.out.println(numDays);
final InetAddress IPAddress = receivePacket.getAddress();
final int port = receivePacket.getPort();
System.out.println("From: " + IPAddress + ":" + port);
System.out.println("Request Message from: "
+ _request.toUpperCase());
if (_educationalInstitution.toLowerCase().equals("concordia")) {
if (portNumber == _mcgillPortNumber) {
_result = _mcgillServer.getNonReturnersData(
_educationalInstitution, numDays);
}
else if (portNumber == _dawsonPortNumber) {
_result = _dawsonServer.getNonReturnersData(
_educationalInstitution, numDays);
}
}
else if (_educationalInstitution.toLowerCase().equals("mcgill")) {
if (portNumber == _concordiaPortNumber) {
_result = _concordiaServer.getNonReturnersData(
_educationalInstitution, numDays);
}
else if (portNumber == _dawsonPortNumber) {
_result = _dawsonServer.getNonReturnersData(
_educationalInstitution, numDays);
}
}
else if (_educationalInstitution.toLowerCase().equals("dawson")) {
if (portNumber == _mcgillPortNumber) {
_result = _mcgillServer.getNonReturnersData(
_educationalInstitution, numDays);
}
else if (portNumber == _dawsonPortNumber) {
_result = _dawsonServer.getNonReturnersData(
_educationalInstitution, numDays);
}
}
// final String capitalizedSentence =
if(_result !=null){
sendData = _result.getBytes();
}
else{
_result="NO DEFAULTERS";
sendData = _result.getBytes();
}
final DatagramPacket sendPacket = new DatagramPacket(sendData,
sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
catch (final SocketException ex) {
System.out.println("UDP Port 9876 is occupied.");
System.exit(1);
}
catch (final IOException e) {
e.printStackTrace();
}
return _result;
}
/**
* Description: Returns the administrator with the list of defaulter who
* have a book past their loan date
*
* @param: Admin username
* @param: Admin password
* @param: Educational Institution
* @param: No of days
*/
public String getNonReturnersData(String educationalInstituion, int numDays) {
//returns data
}
/**
* Description: Using this method the admin invoked server communicates with
* other servers using UDP/IP messages to get their information.Once the
* information is received the admin invoked server sends the result string
* to the admin
*
* @param: Admin username
* @param: Admin password
* @param: Educational Institution
* @param: No of days
*/
@Override
public String getNonReturners(String adminUsername, String adminPassword,
String educationalInstitution, int numDays) throws RemoteException,
Exception {
String _result = null;
String _initiatedServerResult=null;
final ArrayList<String> result = new ArrayList<String>();
final DRMSInterface _concordiaServer = (DRMSInterface) Naming
.lookup("rmi://localhost:1098/concordia");
final DRMSInterface _mcgillServer = (DRMSInterface) Naming
.lookup("rmi://localhost:222/mcgill");
final DRMSInterface _dawsonServer = (DRMSInterface) Naming
.lookup("rmi://localhost:223/dawson");
if (educationalInstitution.toLowerCase().equals("concordia")) {
final Thread t1 = new Thread() {
@Override
public void run() {
try {
result.add(_mcgillServer
.responseData(_mcgillPortNumber));
}
catch (RemoteException | NotBoundException e) {
e.printStackTrace();
}
}
};
t1.setDaemon(true);
t1.start();
final Thread t2 = new Thread() {
@Override
public void run() {
try {
result.add(_dawsonServer
.responseData(_dawsonPortNumber));
}
catch (RemoteException | NotBoundException e) {
e.printStackTrace();
}
}
};
t2.setDaemon(true);
t2.start();
System.out.println("Attemping to connect to " + IPAddress
+ ") via UDP port" + _mcgillPortNumber);
result.add("Attemping to connect to " + IPAddress
+ ") via UDP port" + _mcgillPortNumber);
result.add("/n");
System.out.println("Attemping to connect to " + IPAddress
+ ") via UDP port" + _dawsonPortNumber);
result.add("Attemping to connect to " + IPAddress
+ ") via UDP port" + _dawsonPortNumber);
result.add("/n");
final String _concordiaRequestMessage = educationalInstitution
+ numDays;
System.out.println("Sending data "
+ _concordiaRequestMessage.length() + " bytes to server.");
result.add("Sending data " + _concordiaRequestMessage.length()
+ " bytes to server.");
result.add(_concordiaServer.requestData(_mcgillPortNumber,
_concordiaRequestMessage));
result.add(_concordiaServer.requestData(_dawsonPortNumber,
_concordiaRequestMessage));
_initiatedServerResult=_concordiaServer.getNonReturnersData(
educationalInstitution, numDays);
if(_initiatedServerResult !=null){
result.add(_initiatedServerResult);
}
else{
result.add("No Defaulters in Concordia");
}
}
else if (educationalInstitution.toLowerCase().equals("mcgill")) {
final Thread t1 = new Thread() {
@Override
public void run() {
try {
result.add(_concordiaServer
.responseData(_concordiaPortNumber));
}
catch (RemoteException | NotBoundException e) {
e.printStackTrace();
}
}
};
t1.setDaemon(true);
t1.start();
final Thread t2 = new Thread() {
@Override
public void run() {
try {
result.add(_dawsonServer
.responseData(_dawsonPortNumber));
}
catch (RemoteException | NotBoundException e) {
e.printStackTrace();
}
}
};
t2.setDaemon(true);
t2.start();
System.out.println("Attemping to connect to " + IPAddress
+ ") via UDP port" + _concordiaPortNumber);
result.add("Attemping to connect to " + IPAddress
+ ") via UDP port" + _concordiaPortNumber);
System.out.println("Attemping to connect to " + IPAddress
+ ") via UDP port" + _dawsonPortNumber);
result.add("Attemping to connect to " + IPAddress
+ ") via UDP port" + _dawsonPortNumber);
final String _mcgillRequestMessage = educationalInstitution
+ numDays;
System.out.println("Sending data "
+ _mcgillRequestMessage.length() + " bytes to server.");
result.add("Sending data " + _mcgillRequestMessage.length()
+ " bytes to server.");
result.add(_mcgillServer.requestData(_concordiaPortNumber,
_mcgillRequestMessage));
result.add(_mcgillServer.requestData(_dawsonPortNumber,
_mcgillRequestMessage));
_initiatedServerResult=_mcgillServer.getNonReturnersData(
educationalInstitution, numDays);
if(_initiatedServerResult !=null)
{
result.add(_initiatedServerResult);
}
else{
result.add("No Defaulters in Mcgill");
}
}
else if (educationalInstitution.toLowerCase().equals("dawson")) {
final Thread t1 = new Thread() {
@Override
public void run() {
try {
result.add(_concordiaServer
.responseData(_concordiaPortNumber));
}
catch (RemoteException | NotBoundException e) {
e.printStackTrace();
}
}
};
t1.setDaemon(true);
t1.start();
final Thread t2 = new Thread() {
@Override
public void run() {
try {
result.add(_mcgillServer
.responseData(_mcgillPortNumber));
}
catch (RemoteException | NotBoundException e) {
e.printStackTrace();
}
}
};
t2.setDaemon(true);
t2.start();
System.out.println("Attemping to connect to " + IPAddress
+ ") via UDP port" + _concordiaPortNumber);
result.add("Attemping to connect to " + IPAddress
+ ") via UDP port" + _concordiaPortNumber);
System.out.println("Attemping to connect to " + IPAddress
+ ") via UDP port" + _mcgillPortNumber);
result.add("Attemping to connect to " + IPAddress
+ ") via UDP port" + _mcgillPortNumber);
final String _dawsonRequestMessage = educationalInstitution
+ numDays;
System.out.println("Sending data "
+ _dawsonRequestMessage.length() + " bytes to server.");
result.add("Sending data " + _dawsonRequestMessage.length()
+ " bytes to server.");
result.add(_dawsonServer.requestData(_concordiaPortNumber,
_dawsonRequestMessage));
result.add(_dawsonServer.requestData(_mcgillPortNumber,
_dawsonRequestMessage));
result.add(_concordiaServer.getNonReturnersData(
educationalInstitution, numDays));
_initiatedServerResult=_dawsonServer.getNonReturnersData(
educationalInstitution, numDays);
if(_initiatedServerResult !=null)
{
result.add(_initiatedServerResult);
}
else{
result.add("No Defaulters in Dawson");
}
}
return _result = result.toString();
}
/**
* Description: Creates a remote Concordia server object
* Did the same for the other two servers
*/
public void exportServerConcordia() throws Exception {
Remote _obj = UnicastRemoteObject.exportObject(this,
_concordiaPortNumber);
Registry _r = LocateRegistry.createRegistry(_concordiaPortNumber);
_r.bind("concordia", _obj);
}
public static void main(String args[]) {
try {
DRMSServer concordia = new DRMSServer();
concordia.exportServerConcordia();
System.out.println("Concordia Server is up and running");
DRMSServer mcgill = new DRMSServer();
mcgill.exportServerMcgill();
System.out.println("Mcgill server is up and running");
DRMSServer dawson = new DRMSServer();
dawson.exportServerDawson();
System.out.println("Dawson server is up and running");
//Tried one solution but it didn't work
try {
while (true){
try{
Thread.currentThread();
Thread.sleep (50000000L);
}catch (InterruptedException e) {}
}
} catch (Exception ex) {
System.err.println("Exiting Frequency Keeper Server");
ex.printStackTrace();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
公共类DRMSServer实现DRMSInterface,可序列化{
最终静态int_concordiaPortNumber=1098;
最终静态整数_mcgillPortNumber=222;
最终静态int_dawsonPortNumber=223;
/**
*描述:将UDP请求从被调用的服务器发送到其他服务器
*
*@param:端口号
*@param:Data
*/
公共字符串请求数据(最终整数端口号,最终字符串数据){
StringBuilder sb=新的StringBuilder();
试一试{
final DatagramSocket clientSocket=new DatagramSocket();
最终字节[]接收数据=新字节[1024000];
最终数据包接收数据包=新数据包(
receiveData,receiveData.length);
字节[]发送数据=新字节[1024000];
sendData=data.getBytes();
系统输出打印(“准备发送数据”);
sb.追加(“准备发送数据”);
某人附加(“\n”);
最终数据包sendPacket=新数据包(sendData,
sendData.length、IP地址、端口号);
clientSocket.send(sendPacket);
clientSocket.setSoTimeout(10000);
试一试{
clientSocket.receive(receivePacket);
最终字符串_result=新字符串(receivePacket.getData());
final InetAddress returnIPAddress=receivePacket.getAddress();
final int port=receivePacket.getPort();
System.out.println(“从服务器:+returnIPAddress+”:“
+港口);
sb.append(“从服务器:“+returnIPAddress+”:“+port”);
某人附加(“\n”);
System.out.println(“消息:”+_结果);
sb.追加(“消息:”+_结果);
}
捕获(最终SocketTimeoutException存储){
System.out.println(“发生超时:假定数据包丢失”);
}
//clientSocket.close();
}
捕获(最终SocketException e){
e、 printStackTrace();
}
捕获(最终IOE例外){
e、 printStackTrace();
}
使某人返回字符串();
}
/**
*Description:返回管理员和默认用户列表
*有一本超过借书日期的书。根据
*调用服务器,它发送UDP响应。
*
*@param:端口号
*/
公共字符串responseData(最终整数端口号)引发NotBoundException{
字符串_result=null;
试一试{
@抑制警告(“资源”)
final DatagramSocket serverSocket=新DatagramSocket(端口号,
IP地址);
最终DRMSInterface _concordiaServer=(DRMSInterface)命名
.lookup(“rmi://localhost:1098/concordia");
最终DRMSInterface _mcgillServer=(DRMSInterface)命名
.lookup(“rmi://localhost:222/mcgill");
最终DRMSInterface _dawsonServer=(DRMSInterface)命名
.lookup(“rmi://localhost:223/dawson");
字节[]接收数据=新字节[1024000];
字节[]发送数据=新字节[1024000];
String regex=“(?我想说这行是执行的:
System.exit(1);