java rmi notboundexception - java

I'm trying to develop. My RMI code Initiation that had Server/Client locally for learning purposes. The server part had two interfaces Echo & Sum implemented in the serverRMI and I tried to call from the client side but got this error. Does anyone have any ideas how I can resolve this?
Server.java
public class Server {
public static void main(String[] args) {
try {
MyServerRMI server = new MyServerRMI();
LocateRegistry.createRegistry(1099);
Naming.rebind("rmi://localhost:1099/Server", server);
System.out.println("Server is ready for clients to connect");
} catch (Exception e) {
System.out.println("Server failed: " + e);
}
}
}
MyServerRMI
public class MyServerRMI extends UnicastRemoteObject implements EchoInterface, SumInterface {
public MyServerRMI() throws RemoteException {
super();
}
public String echo(String s) throws RemoteException {
return s;
}
public int sum(int a, int b) throws RemoteException {
return a + b;
}
}
MyClientRMI
public class MyClientRMI {
public static void main(String[] args) {
try {
EchoInterface objetEcho = (EchoInterface) Naming.lookup("rmi://localhost:1099/server");
SumInterface objetSum = (SumInterface) Naming.lookup("rmi://localhost:1099/server");
System.out.println("Echo: " + objetEcho.echo("Hello World from RMI server"));
System.out.println("Sum: " + objetSum.sum(5, 10));
} catch (Exception e) {
System.out.println("Client failed: " + e);
}
}
}

You have not associated the bindings in the client. To do that, you should use:
Registry registry = LocateRegistry.getRegistry(host);
or
Registry registry = LocateRegistry.getRegistry(port);
and then
EchoInterface objetEcho = (EchoInterface) registry.lookup("rmi://localhost:1099/server");
SumInterface objetSum = (SumInterface) registry.lookup("rmi://localhost:1099/server");
also, please use
e.printStackTrace();
instead of just printing e, as the stack trace provides a lot more information.

Related

Multi-Client Server in Java, Maybe threads not running properly or i dont know , cant find out why

I'm programming a server in java that broadcasts the Date() function each second to the clients. The problem is that it worked for only one client but as soon as I started making modifications for multi-client support it broadcasts the Date() only once and then stops, as if the function is being called only once. I can not find what I'm doing wrong so I will just paste the code and hopefully someone will spot the mistake. I searched online but only to end up more confused than I started. For Client program I use the tellnet terminal app for windows.
public class Server
{
private ServerSocket SERVER;
private int PORT;
private Socket CLIENT;
public Server()
{
PORT = 8818;
try
{
SERVER = new ServerSocket(PORT);
System.out.println("Server started on port: " + PORT);
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
public void On() throws IOException
{
while(true)
{
CLIENT = SERVER.accept();
new ClientHandler(CLIENT).start();
}
}
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public class ClientHandler extends Thread
{
private Socket CLIENT;
private OutputStream out;
public ClientHandler(Socket CLIENT)
{
System.out.println("Accepted Connection from: " + CLIENT.getInetAddress());
this.CLIENT = CLIENT;
}
public void run()
{
try
{
out = CLIENT.getOutputStream();
out.write(("Time now is: " + new Date() + "\n").getBytes());
sleep(1000);
}
catch(Exception e)
{
System.out.println(CLIENT.getInetAddress() + " has left the session");
try
{
out.close();
CLIENT.close();
}
catch(IOException j)
{
System.out.println("Unexpected Error");
System.exit(-1);
}
}
}
}
Your modifications nearly worked - below is a running version with only minor modifications from your code.
A part of your modifications you unintentionally removed the while loop in the run function, which means the Date() function is in fact only called once. To see this, remove the while loop in run() and after the Date is printed (in the telnet window) the message "Done with the run function." is printed.
I added an identifier to each client which is printed with the date. The static cnt class field makes sure that each client has a different id.
I started separate clients in separate command prompt terminals using
telnet localhost 8818 such that they were running at the same time. At the bottom is the output from the 3rd client.
I did switch the code to camelCase convention (start variables with a lower case letter and capitalizing each new word) since all CAPS is usually reserved for constants and the change made the code easier to read for me.
public class Server
{
private ServerSocket server;
private int port;
private Socket client;
public Server()
{
port = 8818;
try
{
server = new ServerSocket(port);
System.out.println("Server started on port: " + port);
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
public void on() throws IOException
{
while(true)
{
client = server.accept();
new ClientHandler(client).start();
}
}
}
public class ClientHandler extends Thread {
private Socket client;
private OutputStream out;
private int id;
private static int cnt=0;
public ClientHandler(Socket client) {
System.out.println("Accepted Connection from: " + client.getInetAddress());
this.client = client;
id=cnt;
cnt++;
}
public void run() {
try {
out = client.getOutputStream();
while (true) {
out.write(("Client " + id + ": Time now is: " + new Date() + "\n").getBytes());
sleep(1000);
}
} catch (Exception e) {
System.out.println(client.getInetAddress() + " has left the session");
try {
out.close();
client.close();
} catch (IOException j) {
System.out.println("Unexpected Error");
System.exit(-1);
}
}
System.out.println("Done with the run function.");
}
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Server s = new Server();
s.on();
}
}

How to do naming system with RMI in different hosts?

I have two java classes one is the client and the other is the server, in the client I have to give the server ip address, but I want to make it dynamique so the client knows the ip of a third machine(naming system) which search for the method (like DNS) and returns the ip address of the specific server who provides this method.
Edited:
classe client :
public class Client {
private Client() {}
public static void main(String[] args) {
String host = (args.length < 1) ? null : args[0];
try {
//Registry registry = LocateRegistry.getRegistry(host);
Registry registry = LocateRegistry.getRegistry("192.168.1.9",1091);
Calculator stub = (Calculator) registry.lookup("Hello");
String response = stub.add(4,2);
System.out.println("response: " + response);
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
server :
public class Server implements Calculator{
public Server() {}
public String add(int a,int b) {
return "Hello, a+b= "+(a+b);
}
public String sub(int a,int b) {
return "Hello, a-b= "+(a-b);
}
public static void main(String args[]) {
try {
Server obj = new Server();
Calculator stub = (Calculator) UnicastRemoteObject.exportObject(obj, 0);
// Bind the remote object's stub in the registry
Registry registry = LocateRegistry.createRegistry(1091);
registry.bind("Hello", stub);
System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}
You can't do this with the RMI Registry. Only a process running in the same host as the Registry can bind to it. You would have to use a different naming service such as LDAP.
However the rest of your description is what RMI already does. You look up a name in the Registry and it returns you a stub that knows how to communicate with the corresponding remote object.

Websocket server.run() don't allow followed codes to start

I have the following web-socket server code from (https://github.com/TooTallNate/Java-WebSocket):
public class WebsocketServer extends WebSocketServer {
private static int PORT = 2005;
private Set<WebSocket> conns;
public WebsocketServer() {
super(new InetSocketAddress(PORT));
conns = new HashSet<>();
}
#Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
conns.add(conn);
System.out.println("New connection from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
#Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
conns.remove(conn);
System.out.println("Closed connection to " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
#Override
public void onMessage(WebSocket conn, String message) {
System.out.println("Received: " + message);
for (WebSocket sock : conns) {
sock.send(messageToSend);
}
}
#Override
public void onError(WebSocket conn, Exception ex) {
ex.printStackTrace();
if (conn != null) {
conns.remove(conn);
// do some thing if required
}
System.out.println("ERROR from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
public static void main(String[] args) throws IOException, InterruptedException {
WebsocketServer server = new WebsocketServer();
server.run();
BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String in = sysin.readLine();
server.sendToAll(in);
if (in.equals("exit")) {
server.stop();
break;
} else if (in.equals("restart")) {
server.stop();
server.start();
break;
}
}
}
public void sendToAll(String text) {
Collection<WebSocket> con = connections();
synchronized (con) {
for (WebSocket c : con) {
c.send(text);
}
}
}
}
The codes works fine, but all codes that comes after server.run(); won't start/work! that part I need to send messages from Java console to client.
What I am doing wrong?
Note: My client works in JavaScript and can connect to the server
You need to start() Runnable class, not run() it directly
server.start();
instead of
server.run();

TcpSockets do not connect

I am trying to establish a TCP connection between a laptop as a client and a pc as a server.
My goal is to use the server to send messages between two android devices. The server has a public IP address. To test the connection, I have written two simple Java classes:
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public ServerSocket welcome;
public Socket soc;
public int listeningPort = /* default port */;
public TcpServer() {
}
public static void main(String[] args) {
TcpServer ms = new TcpServer();
if(args.length > 0) {
ms.listeningPort = Integer.parseInt(args[0]);
}
ms.listen();
}
public void listen() {
try {
welcome = new ServerSocket(listeningPort);
System.out.println(">>> listening on port " + listeningPort + " <<<");
soc = welcome.accept();
System.out.println(">>> got a new connection from "
+ soc.getInetAddress().toString() + " <<<");
while (true) {
try {
byte b[] = new byte[1024];
soc.getInputStream().read(b, 0, 1);
System.out.print((char) (b[0]));
} catch (Exception e) {
System.err.println(e);
}
}
} catch (Exception e) {
System.err.println(e);
}
}
}
import java.net.Socket;
public class TcpSendClient {
private String serverIp = /* some ip */;
public int port = /* default port */;
private SendThread st;
public TcpSendClient() {
}
public static void main(String[] args) {
TcpSendClient client = new TcpSendClient();
if(args.length > 0) {
client.port = Integer.parseInt(args[0]);
}
client.send();
}
public void send() {
System.out.println("Try to connet to " + serverIp + " via Port" + port);
st = new SendThread(serverIp, port);
st.start();
}
class SendThread extends Thread {
private Socket soc;
public SendThread(String theIp, int thePort) {
try {
soc = new Socket(theIp, thePort);
} catch (Exception e) {
System.err.println(e);
}
}
public void run() {
try {
while (true) {
String toSend = "Hello ";
soc.getOutputStream().write(toSend.getBytes());
Thread.sleep(800);
System.out.println("sent");
}
} catch (Exception e) {
System.err.println(e);
}
}
}
}
When I run both Java files on the server pc, the connection works fine. It also worked if I set up a local Wi-Fi with one laptop and connect to it using another laptop.
But, when I run the client file from a laptop connected to the internet, I am not able to get a connection.
In the firewall on the Server, I opened a number of ports for the connection and the laptop I use as a client has the firewall disabled.
Apart from the firewall, I do not really know what to look into in order to get the connection running. Any ideas as to the cause of my problem and a solution?
I found the solution: The windows firewall was still blocking the ports for Java. It took me a little longer to figure this out, because I was not registered as admin on that pc and could not see the rules.

RMI chat over Internet

I managed to make the client send objects to the server and the server does reply correctly but only to the client who sent the object, I had to forward ports on the server side and allowed port connections on the server side, now I can't seem to send a reply/message to a specific client and always get a connection refused error, meddling with portforwardind/firewall on the client side is not possible since anyone should be able to use the chat(the client must stay a client and not become a server). Any ideas how to make this work ? I heard about http tunneling or rmi proxy but how does it work code-wise ?
here's my main code on the client side :
public class Main {
public static void main(String [] args) {
String input;
Scanner in = new Scanner(System.in);
input = in.nextLine();
try
{
Message b =(Message) Naming.lookup("//xx.xx.xx.xx:1099/Message");
Client c=new Client(input);
UnicastRemoteObject.exportObject(c, 1100);
b.addUser(c);
while(true)
{
input = in.nextLine();
if(input.contentEquals("deconnection"))
{
b.exit();
break;
}
else if(input.startsWith(">"))
{
b.broadcast(c,"test");
}
}
in.close();
}
catch (NotBoundException re) { System.out.println(re) ; }
catch (RemoteException re) { System.out.println(re) ; }
catch (MalformedURLException e) { System.out.println(e) ; }
}
}
on the server side :
public class Serveur
{
public static void main(String [] args) {
try {
MessageImpl objLocal = new MessageImpl();
Naming.rebind("rmi://localhost:"+1099+"/Message" , UnicastRemoteObject.exportObject(objLocal, 1100)) ;
System.out.println("Serveur pret");
}
catch (RemoteException re) { System.out.println(re) ; }
catch (MalformedURLException e) { System.out.println(e) ; }
}
}
with the MessageImpl.java where the clientlist is found :
public class MessageImpl
implements Message {
public Vector<ClientInterface> clientlist;
public MessageImpl () throws RemoteException {super();listec=new Vector<ClientInterface>();};
public String envoiMessage() throws RemoteException {
return( "message test" );
}
public boolean isNew(ClientInterface c) throws RemoteException
{
return false;
}
public String test() throws RemoteException
{
System.out.println("re");
return "test";
}
public void addUser(ClientInterface c) throws RemoteException
{
test();
clientlist.add(c);
}
public void broadcast(ClientInterface c,String message) throws RemoteException
{
int i;
for(i=0;i<clientlist.size();i++)
{
if(clientlist.elementAt(i).getUsername().equals(c.getUsername()))
{}
else
{
clientlist.elementAt(i).getMessage(c.getUsername()+" : "+message);
}
}
}
public String exit() throws RemoteException
{
try{
return "exiting messenger";
}
catch(Exception e){return "erreur deconnection";}
}
}
If 'meddling' with the client firewall isn't possible, your system is unimplementable as designed. You would have to use polling instead of callbacks on the client side.

Categories

Resources