sockets in rmi, help needed.
hi,
I need a help on using sockets in rmi for communication between the server and the client. I am trying to establish a communication between the server and client through sockets after the remote method call is invoked but before it is fulfilled. I my code the socket is not establishing in the client side. Do help me out at the earliest pls... thanks in advance..
write properly what actually you want 2 do?The RMI system implemented using the socket programming and it has the protocol JRMP/IIOP that is running over the TCP connection.Try 2 figure out what actually u want 2 do.
I am trying to use sockets inside a rmi. In that i have established a server socket in the client side. It listens from the server in some port.
First the client invokes a remote object. Before server sending the actual request of the requested by the remote object i want to make some communication between the server and client through sockets.
So I created a ServerSocket in the client side. The problem I have is the ServerSocket is not listening to the server request.
Here i ve my code.I cant figure out what mistake i have done. It also dont show any error. As i am new to RMI and sockets i am in need of help. So pls do help me... Thanks in advance.
[b]FileClient.java[\b]
import java.io.*;
import java.net.*;
import java.rmi.*;
public class FileClient implements Runnable {
Socket soc;
String filename;
byte[] filedata;
public FileClient(String filename, String host)
{
this.filename = filename;
try
{
ServerSocket ss=new ServerSocket(5000);
System.out.println("Created a socket"+ss);
String name = "//" + host + "/FileServer";
FileInterface fi = (FileInterface) Naming.lookup(name);
System.out.println("Got the interface "+fi);
while(true)
{
soc=ss.accept();
new Thread(this).start();
}
} catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String argv[]) {
if(argv.length != 2) {
System.out.println("Usage: java FileClient fileName machineName");
System.exit(0);
}
new FileClient(argv[0], argv[1]);
}
public void run() {
try {
System.out.println(soc);
InputStream is=soc.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
System.out.println("Created the readers"+br);
String req=br.readLine();
System.out.println("Going to print request");
System.out.println(req);
String password=br.readLine();
OutputStream os=soc.getOutputStream();
PrintStream ps=new PrintStream(os);
ps.println(password);
filedata = fi.downloadFile(filename);
File file = new File(filename);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(file.getName()));
output.write(filedata,0,filedata.length);
output.flush();
output.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
[\code]
[b]FileImpl.java[/b]
import java.io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FileImpl extends UnicastRemoteObject implements FileInterface
{
private String name;
public FileImpl(String s) throws RemoteException
{
super();
name=s;
}
public byte[] downloadFile(String fileName)
{
try
{
Socket soc=new Socket(RemoteServer.getClientHost(),5000);
OutputStream os=soc.getOutputStream();
PrintStream ps=new PrintStream(os);
System.out.println("Going to send message");
ps.println("Enter the password : ");
System.out.println("Sent message");
InputStream is=soc.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
String res=br.readLine();
PasswordControl pc=new PasswordControl(res,br);
System.setSecurityManager(pc);
File file=new File(fileName);
byte [] buffer=new byte[(int)file.length()];
BufferedInputStream input=new BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
return(buffer);
}
catch(Exception e)
{
System.out.println("FileImpl: "+e.getMessage());
e.printStackTrace();
return(null);
}
}
public class PasswordControl extends SecurityManager
{
String password;
BufferedReader br;
public PasswordControl(String password,BufferedReader br)
{
this.password=password;
this.br=br;
}
public boolean accessOk()
{
String response = "";
try
{
if(response.equals(password))
return true;
else
return false;
}
catch(Exception e)
{
return false;
}
}
public void checkRead(String fname)
{
if(fname.equals("sample.txt"))
{
if(!accessOk())
{
super.checkRead(fname);
throw new SecurityException("Access denied to read from the file sample.txt");
}
else
{
FilePermission fp=new FilePermission(fname,"read");
checkPermission(fp);
}
}
}
}
}
FileServer.java
import java.rmi.*;
import java.io.*;
public class FileServer
{
public static void main(String []args)
{
if(System.getSecurityManager()==null)
{
System.setSecurityManager(new RMISecurityManager());
}
try
{
FileImpl fi=new FileImpl("FileServer");
Naming.rebind("FileServer",fi);
System.out.println("Server bound"+fi);
}
catch(Exception e)
{
System.out.println("FileServer: "+e.getMessage());
}
}
}
FileInterface.java
import java.rmi.*;
public interface FileInterface extends Remote
{
public byte[] downloadFile(String fileName) throws RemoteException;
}
I am trying to use sockets inside a rmi. In that i have established a server socket in the client side. It listens from the server in some port.
First the client invokes a remote object. Before server sending the actual request of the requested by the remote object i want to make some communication between the server and client through sockets.
So I created a ServerSocket in the client side. The problem I have is the ServerSocket is not listening to the server request.
Here i ve my code.I cant figure out what mistake i have done. It also dont show any error. As i am new to RMI and sockets i am in need of help. So pls do help me... Thanks in advance.
In my example i am trying to verify the password before the server downloads the file for the client. So i want the verification done through sockets and download file using RMI.
FileInterface.java
import java.rmi.*;
public interface FileInterface extends Remote
{
public byte[] downloadFile(String fileName) throws RemoteException;
}
FileServer.java
import java.rmi.*;
import java.io.*;
public class FileServer
{
public static void main(String []args)
{
if(System.getSecurityManager()==null)
{
System.setSecurityManager(new RMISecurityManager());
}
try
{
FileImpl fi=new FileImpl("FileServer");
Naming.rebind("FileServer",fi);
System.out.println("Server bound"+fi);
}
catch(Exception e)
{
System.out.println("FileServer: "+e.getMessage());
}
}
}
FileImpl.java
import java.io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FileImpl extends UnicastRemoteObject implements FileInterface
{
private String name;
public FileImpl(String s) throws RemoteException
{
super();
name=s;
}
public byte[] downloadFile(String fileName)
{
try
{
Socket soc=new Socket(RemoteServer.getClientHost(),5000);
OutputStream os=soc.getOutputStream();
PrintStream ps=new PrintStream(os);
System.out.println("Going to send message");
ps.println("Enter the password : ");
System.out.println("Sent message");
InputStream is=soc.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
String res=br.readLine();
PasswordControl pc=new PasswordControl(res,br);
System.setSecurityManager(pc);
File file=new File(fileName);
byte [] buffer=new byte[(int)file.length()];
BufferedInputStream input=new BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
return(buffer);
}
catch(Exception e)
{
System.out.println("FileImpl: "+e.getMessage());
e.printStackTrace();
return(null);
}
}
public class PasswordControl extends SecurityManager
{
String password;
BufferedReader br;
public PasswordControl(String password,BufferedReader br)
{
this.password=password;
this.br=br;
}
public boolean accessOk()
{
String response = "";
try
{
if(response.equals(password))
return true;
else
return false;
}
catch(Exception e)
{
return false;
}
}
public void checkRead(String fname)
{
if(fname.equals("sample.txt"))
{
if(!accessOk())
{
super.checkRead(fname);
throw new SecurityException("Access denied to read from the file sample.txt");
}
else
{
FilePermission fp=new FilePermission(fname,"read");
checkPermission(fp);
}
}
}
}
}
FileClient.java
import java.io.*;
import java.net.*;
import java.rmi.*;
public class FileClient implements Runnable {
Socket soc;
String filename;
byte[] filedata;
public FileClient(String filename, String host)
{
this.filename = filename;
try
{
ServerSocket ss=new ServerSocket(5000);
System.out.println("Created a socket"+ss);
String name = "//" + host + "/FileServer";
FileInterface fi = (FileInterface) Naming.lookup(name);
System.out.println("Got the interface "+fi);
while(true)
{
soc=ss.accept();
new Thread(this).start();
}
} catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String argv[]) {
if(argv.length != 2) {
System.out.println("Usage: java FileClient fileName machineName");
System.exit(0);
}
new FileClient(argv[0], argv[1]);
}
public void run() {
try {
System.out.println(soc);
InputStream is=soc.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
System.out.println("Created the readers"+br);
String req=br.readLine();
System.out.println("Going to print request");
System.out.println(req);
String password=br.readLine();
OutputStream os=soc.getOutputStream();
PrintStream ps=new PrintStream(os);
ps.println(password);
filedata = fi.downloadFile(filename);
File file = new File(filename);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(file.getName()));
output.write(filedata,0,filedata.length);
output.flush();
output.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
Your client is starting a new thread per accepted connection which gets a password then tries to call the remote method.
Your remote method opens a connection to the client.
The client will start a new thread to handle this connection and then get the password and try to call the remote method.
Your remote method then opens a connection to the client ...
The problem is in the first sentence. Your ServerSocket-handling thread needs to be independent of the remote method otherwise you just have an infinite regression.
ejpa at 2007-7-13 8:53:10 >

Thank you very much for your response. i tried as u said but still the problem persists. Can u tell me how can i make the ServerSocket thread independent of the Remote call? Is it possible to implement this program without using threads. If so how can i do that? Cos threads are really confusing me much. Thank you in advance.
What did you try and what problem persisted? You need to start a separate thread accepting connections from the ServerSocket and probably a thread per accepted connection as well if you are expecting more than one.
There is no solution without using another thread if you want a direct Socket connection. (An RMI callback to the client would take care of the threading issues for you but you specifically said you wanted a socket connection.) The thread calling the remote method can't do anything until the remote method returns.
ejpa at 2007-7-13 8:53:10 >

I could not still resolve the problem as mentioned before. I also dont know how to implement your idea which u gave as i am new to these concepts. I am getting a problem in the FileClient program as it is not accepting the socket.I have attached the program and its output. In the program i am not getting error or exception while running. The problem is the program remains still. Please help me out with codings if possible at the earliest.
Thank you in advance.
FileInterface.java:
=============
import java.rmi.*;
public interface FileInterface extends Remote
{
public byte[] downloadFile(String fileName) throws RemoteException;
}
FileImpl.java:
==========
import java.io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FileImpl extends UnicastRemoteObject implements FileInterface
{
private String name;
public FileImpl(String s) throws RemoteException
{
super();
name=s;
}
public byte[] downloadFile(String fileName)
{
try
{
Socket soc=new Socket(getClientHost(),5000);
OutputStream os=soc.getOutputStream();
PrintStream ps=new PrintStream(os);
System.out.println("Going to send message");
ps.println("Enter the password : ");
System.out.println("Sent message");
InputStream is=soc.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
String res=br.readLine();
PasswordControl pc=new PasswordControl("ssss",br);
System.setSecurityManager(pc);
File file=new File(fileName);
byte [] buffer=new byte[(int)file.length()];
BufferedInputStream input=new BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
return(buffer);
}
catch(Exception e)
{
System.out.println("FileImpl: "+e.getMessage());
e.printStackTrace();
return(null);
}
}
public class PasswordControl extends SecurityManager
{
String password;
BufferedReader br;
public PasswordControl(String password,BufferedReader br)
{
this.password=password;
this.br=br;
}
public boolean accessOk()
{
String response = "";
try
{
response=br.readLine();
if(response.equals(password))
return true;
else
return false;
}
catch(Exception e)
{
return false;
}
}
public void checkRead(String fname)
{
if(fname.equals("sample.txt"))
{
if(!accessOk())
{
super.checkRead(fname);
throw new SecurityException("Access denied to read from the file sample.txt");
}
else
{
FilePermission fp=new FilePermission(fname,"read");
checkPermission(fp);
}
}
}
}
}
FileServer.java:
============
import java.rmi.*;
import java.io.*;
public class FileServer
{
public static void main(String []args)
{
if(System.getSecurityManager()==null)
{
System.setSecurityManager(new RMISecurityManager());
}
try
{
FileImpl fi=new FileImpl("FileServer");
Naming.rebind("FileServer",fi);
System.out.println("Server bound"+fi);
}
catch(Exception e)
{
System.out.println("FileServer: "+e.getMessage());
}
}
}
FileClient.java:
==========
import java.io.*;
import java.net.*;
import java.rmi.*;
public class FileClient implements Runnable {
Socket soc;
String filename;
String host;
byte[] filedata;
public FileClient(String filename, String host)
{
this.filename = filename;
this.host=host;
try
{
String name = "//" + host + "/FileServer";
FileInterface fi = (FileInterface) Naming.lookup(name);
filedata = fi.downloadFile(filename);
ServerSocket ss=new ServerSocket(5000);
System.out.println("Created a socket"+ss);
System.out.println("Got the interface "+fi);
while(true)
{
soc=ss.accept();
System.out.println("Socket accepted and thread going to start");
new Thread(this).start();
}
} catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String argv[]) {
if(argv.length != 2) {
System.out.println("Usage: java FileClient fileName machineName");
System.exit(0);
}
new FileClient(argv[0], argv[1]);
}
public void run() {
try {
System.out.println(soc);
InputStream is=soc.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
System.out.println("Created the readers"+br);
String req=br.readLine();
System.out.println("Going to print request");
System.out.println(req);
String password=br.readLine();
OutputStream os=soc.getOutputStream();
PrintStream ps=new PrintStream(os);
ps.println(password);
File file = new File(filename);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(file.getName()));
output.write(filedata,0,filedata.length);
output.flush();
output.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
SERVER OUTPUT:
==============
C:\RMI>java FileServer
Server boundFileImpl[RemoteStub [ref: [endpoint:[10.1.13.42:2576](local),objID:[
0]]]]
Going to send message
Sent message
(After this it remains still)
CLIENT OUTPUT:
==============
C:\RMI>java FileClient c:\sample.txt 1127.0.0.1
//1127.0.0.1/FileServer
Created a socketServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=5000]
Got the interface FileImpl_Stub[UnicastRef [liveRef: [endpoint:[10.1.13.42:2576
(remote),objID:[1f33675:10a21d86a82:-8000, 0]]]]
(After this it remains still)
You still aren't creating any Threads, and this code is never going to work until you do.
a. Your client code after the downloadFile() executes after downloadFile() returns, not a moment sooner.
b. So there is no ServerSocket in existence for the other end to connect to while downloadFile() is running.
c. You need to create the ServerSocket before calling downloadFile(), not after it.
d. You need to put the accept() and Socket-handling code into a separate thread. Look it up! java.lang.Thread, and while you're at it have a look at the Sockets documentation and tutorial.
On the other hand what I really don't understand is why you aren't just sending the password as a parameter to downloadFile() and forgetting all this socket nonsense.
ejpa at 2007-7-13 8:53:10 >

Thank you very much for your reply. I started learning the sockets and try out what u said. I am using this socket inside RMI instead of passing as a parameter cos i was said to do so for my academic project. Once again Thank you very much.
OK, understood, read up on Thread.BTW presuambly you have finished the assignment by now, but whoever instructed or advised you to use RMI and Sockets was giving you bad advice, or imposing a pointless requirement if it was coursework.
ejpa at 2007-7-13 8:53:10 >

I have tried by creating a seperate thread but still the same output is coming. I modified the FileClient.java program by creating another class Download.java which is called on thereby creating seperate thread.
Below is my code. I dont know wat is the mistake in it. I am very much in need of help cos this is my academic project and I got to complete it. If possible pls tell me the correction to be made or with some codings pls. Thank you in advance.
FileClient.java
import java.io.*;
import java.net.*;
import java.rmi.*;
public class FileClient implements Runnable {
Socket soc;
String filename;
String host;
byte[] filedata;
public FileClient(String filename, String host)
{
this.filename = filename;
this.host=host;
try
{
new Thread(this).start();
String name = "//" + host + "/FileServer";
FileInterface fi = (FileInterface) Naming.lookup(name);
System.out.println(name);
System.out.println("Got the interface "+fi);
filedata = fi.downloadFile(filename);
System.out.println("Socket accepted and thread going to start");
new Thread(this).start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String argv[])
{
if(argv.length != 2)
{
System.out.println("Usage: java FileClient fileName machineName");
System.exit(0);
}
new FileClient(argv[0], argv[1]);
}
public void run()
{
try
{
ServerSocket ss=new ServerSocket(5000);
System.out.println("Created a socket"+ss);
soc=ss.accept();
System.out.println(soc);
Download dl=new Download(filename,soc,filedata);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Download.java
import java.io.*;
import java.net.*;
import java.rmi.*;
public class Download implements Runnable
{
public void run()
{
try
{
InputStream is=soc.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
System.out.println("Created the readers"+br);
String req=br.readLine();
System.out.println("Going to print request");
System.out.println(req);
String password=br.readLine();
OutputStream os=soc.getOutputStream();
PrintStream ps=new PrintStream(os);
ps.println(password);
File file = new File(fileName);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(file.getName()));
output.write(filedata,0,filedata.length);
output.flush();
output.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public Download(String fileName,Socket soc,byte[] filedata)
{
this.fileName=fileName;
this.soc=soc;
this.filedata=filedata;
th=new Thread();
th.start();
}
String fileName;
Socket soc;
byte[] filedata=null;
Thread th;
}
This is still a ridiculous way to do it. Please tell your instructor I said so: I've written a book on RMI: see http://www.rmiproxy.com/javarmi). What you should be doing is adding a password parameter to the downloadFile() remote method. Nothing could be simpler and it will take you five minutes from here to working code.
Re your code, there are numerous problems.
a. You start the FileData client thread twice.
b. The second one will fail with a BindException: delete the second start().
c. You are processing filedata in the wrong place. You can't get the filedata until the downloadFile() remote method returns: this won't happen until after you've supplied the password, so you can't process it where you send the password because you haven't got it yet. This processing should be inline with & after the remote method call.
d. You've been at this five or six weeks and you still haven't got it right. Time to quit. I strongly suggest that you ditch this approach and follow my advice in the first paragraph. Maybe your instructor will learn something too.
ejpa at 2007-7-13 8:53:10 >

Thank You very much for your advice. I told my instructor that it cant be done so but he still say me to try. And also I cant get away from this as this is my academic project. And also i got to finish this by next week. Once again thank you for your kind help. I don't know how i am going to complete it as he said but anyway I will try my best.
Regards.
I didn't say it can't be done, it can, and you have enough information to do it. I said it is a stupid way to do it and it is.
ejpa at 2007-7-13 8:53:10 >
