java RMI + source hitting server is from internet or from intranet - java

In java RMI i am building a chat application. But i am not able to figure out a way to find out, whether the IP which is hitting my server is from my internal organization network(INTRANET) or from external world(INTERNET).
Right now i am using
try {
System.setProperty("java.rmi.server.hostname",InetAddress.getLocalHost().getHostAddress());
Registry statusRegistry = LocateRegistry.createRegistry(ChatConstants.statusPort);
ChatInterface chat = new ChatImpl(ChatConstants.statusPort) ;
statusRegistry.rebind("statusconnection",chat);
System.out.println("RMIStatusConnection Server is started...");
} catch (RemoteException e) {
System.out.println("RMIStatusConnection failed...");
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
}

Try RemoteServer.getClientHost(), but it may only provide the address of the nearest NAT device.
NB there's not much point in setting java.rmi.server.hostname like that. That's the default. You only need to set it if there's something wrong with the default setting.

Related

Sending ASCII and protocol commands to server

I managed to setup a client and server connection using Java socket. After checking the connection had been establish, I tried sending Protocol commands that are provided by the SDK from the server and I'm using a JButton to execute the commands.
Examples of the commands are play, stop and ping the server.
The code below shows how I setup the connection and send the protocol commands
public void socket1()
{
Socket MyClient;
try {
MyClient = new Socket("192.168.10.61",9993);
os = new DataOutputStream(MyClient.getOutputStream());
is = new DataInputStream(MyClient.getInputStream());
lblerror.setText("Connected");
MyClient.getOutputStream().write("play".getBytes("US-ASCII"));
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
lblerror.setText("Don't know about host: hostname");
} catch (IOException e) {
// TODO Auto-generated catch block
lblerror.setText("Couldn't get I/O for the connection to: hostname");
}
}
After pressing the button on the GUI, The server did not response to the command 'play' and there is no error.
As Scarry Wombat wrote, use os.write()
But instead of .write() use .writeBytes(),
because you want to send a byte array(?). Alternatively you could send a String with UTF-encoding by using .writeUTF()

How to receive public IP and Port using Stun and ice4j

I'll try to be brief.
I wish to create communication between 2 java apps (that will later be transported to android) without passing through a server. As such, I have spent weeks looking around, and after a lot of work I found stun and ice4j. The best explanation of how to use ice4j I found here, and it pretty much showed me what I need to do to add stun servers to an agent (I don't really know what an agent is, just that it manages my communications with STUN and TURN), through this code:
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.ice4j.Transport;
import org.ice4j.TransportAddress;
import org.ice4j.ice.Agent;
import org.ice4j.ice.IceMediaStream;
import org.ice4j.ice.harvest.StunCandidateHarvester;
public class ice4jTesting {
public static void main(String[] args) {
Agent agent = new Agent();
String[] hostnames = new String[] {"jitsi.org", "numb.viagenie.ca", "stun.ekiga.net"};
for(String hostname: hostnames) {
try {
TransportAddress address;
address = new TransportAddress(InetAddress.getByName(hostname), 3478, Transport.UDP);
agent.addCandidateHarvester(new StunCandidateHarvester(address));
} catch (UnknownHostException ex) {
Logger.getLogger(SimpleStun.class.getName()).log(Level.SEVERE, null, ex);
}
}
IceMediaStream stream = agent.createMediaStream("audio");
int port = 5000;
try {
agent.createComponent(stream, Transport.UDP, port, port, port+100);
// The three last arguments are: preferredPort, minPort, maxPort
} catch (IllegalArgumentException | IOException ex) {
Logger.getLogger(SimpleStun.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
however, after this the tutorial utilizes SDPUtils, a class that is in the source code of ice4j I found on github, to recieve the SDP information from the agent. However I got ice4j.jar from the central maven repository, and added it to my netbeans regular project (I did this because I am not very familiar with maven, and just wanted a regular library on my regular project). This jar library does not have the SDPUtils class, and since I don't really understand enough of this code to fix it myself, I was wondering if any of you could help me either fix the code above, or show me an example of how to answer the question on the title.
However, unless you can either do what I said in the last sentence, or point me to some sample code, your help will most likely not be useful, since I am mentally incapable of understanding the theory behind this completely because of the many concepts I do not know.
I have until the end of this week to figure this out, and if I don't I'm pretty screwed. So please, if you can or know someone that can help, I would extremely appreciate it.
Thanks for reading it so far and trying to help :)
There you go
SdpUtils.java
Actually i'm also working on the same as my University project. From last week i'm digging web for p2p connection establish over nat.
I know that form where you got above Code snipet, i would like to inform you that there is errors in that code Here is the one that i corrected
import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import org.ice4j.Transport;
import org.ice4j.TransportAddress;
import org.ice4j.ice.Agent;
import org.ice4j.ice.IceMediaStream;
import org.ice4j.ice.harvest.StunCandidateHarvester;
public class IceTest {
public static void main(String[] args) throws Exception {
Agent agent = new Agent(); // A simple ICE Agent
/*** Setup the STUN servers: ***/
String[] hostnames = new String[] { "jitsi.org", "numb.viagenie.ca", "stun.ekiga.net" };
// Look online for actively working public STUN Servers. You can find
// free servers.
// Now add these URLS as Stun Servers with standard 3478 port for STUN
// servrs.
for (String hostname : hostnames) {
try {
// InetAddress qualifies a url to an IP Address, if you have an
// error here, make sure the url is reachable and correct
TransportAddress ta = new TransportAddress(InetAddress.getByName(hostname), 3478, Transport.UDP);
// Currently Ice4J only supports UDP and will throw an Error
// otherwise
agent.addCandidateHarvester(new StunCandidateHarvester(ta));
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* Now you have your Agent setup. The agent will now be able to know its
* IP Address and Port once you attempt to connect. You do need to setup
* Streams on the Agent to open a flow of information on a specific
* port.
*/
IceMediaStream stream = agent.createMediaStream("audio");
int port = 5000; // Choose any port
try {
agent.createComponent(stream, Transport.UDP, port, port, port + 100);
// The three last arguments are: preferredPort, minPort, maxPort
} catch (BindException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*
* Now we have our port and we have our stream to allow for information
* to flow. The issue is that once we have all the information we need
* each computer to get the remote computer's information. Of course how
* do you get that information if you can't connect? There might be a
* few ways, but the easiest with just ICE4J is to POST the information
* to your public sever and retrieve the information. I even use a
* simple PHP server I wrote to store and spit out information.
*/
String toSend = null;
try {
toSend = SdpUtils.createSDPDescription(agent);
// Each computersends this information
// This information describes all the possible IP addresses and
// ports
} catch (Throwable e) {
e.printStackTrace();
}
/*The String "toSend" should be sent to a server. You need to write a PHP, Java or any server.
* It should be able to have this String posted to a database.
* Each program checks to see if another program is requesting a call.
* If it is, they can both post this "toSend" information and then read eachother's "toSend" SDP string.
* After you get this information about the remote computer do the following for ice4j to build the connection:*/
String remoteReceived = ""; // This information was grabbed from the server, and shouldn't be empty.
SdpUtils.parseSDP(agent, remoteReceived); // This will add the remote information to the agent.
//Hopefully now your Agent is totally setup. Now we need to start the connections:
agent.addStateChangeListener(new StateListener()); // We will define this class soon
// You need to listen for state change so that once connected you can then use the socket.
agent.startConnectivityEstablishment(); // This will do all the work for you to connect
}
}
This code Requires SIP server to be setup and the one on ice4j test is saying something else just have a look at Ice.java

Stopping RMI Server (Java)

I created a sucessful RMI server, thank god for that :)
It works perfectly..
I have a JForm and it gets activated clicking on a button.
Altough i wanted to create too a button to deactivate it, but i am having a problems to unexport it.
Ok then and this is the way i was trying to exporting and terminating the RMI Server
private void btStopServerActionPerformed(java.awt.event.ActionEvent evt) {
try {
// Nome do objecto
String objectname = txtObjectName.getText();
// obtem o número da porta
int port = Integer.parseInt(txtServerPort.getText());
RemoteMessageObject remote = new RemoteMessageObject();
Registry registry = LocateRegistry.getRegistry(port);
UnicastRemoteObject.unexportObject(LocateRegistry.getRegistry(port), true);
registry.unbind(objectname);
System.out.println("Server offline");
} catch (IOException ex) {
Logger.getLogger(ServerGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (NotBoundException ex) {
Logger.getLogger(ServerGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
I get this exception:
java.rmi.NoSuchObjectException: object not exported
at the line:
UnicastRemoteObject.unexportObject(LocateRegistry.getRegistry(port), true);
What am i doing wrong here?
Solved................
I discovered it before :P
Anywway thanks #EJP for the correct answer.
So the solution for me was to create the Register when the class starts as a public variable, so it could be use inside both click events (Start server and stop server).
I removed too a lot of nonsense stuff that was not necessary for disabling the RMI server just like #EJP sayed.
Its now working this way:
private void btStopServerActionPerformed(java.awt.event.ActionEvent evt) {
try {
// Nome do objecto
String objectname = txtObjectName.getText();
// obtem o número da porta
int port = Integer.parseInt(txtServerPort.getText());
Registry registry = LocateRegistry.getRegistry(port);
UnicastRemoteObject.unexportObject(this.registry, true);
registry.unbind(objectname);
System.out.println("Server offline");
} catch (IOException ex) {
GuiUtils.addText(txtLog, "Erro", "Servidor desligado");
btStopServer.setEnabled(false);
btStartServer.setEnabled(true);
} catch (NotBoundException ex) {
Logger.getLogger(ServerGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
You need to unexport the object returned by LocateRegistry.createRegistry(). The object returned by getRegistry() isn't the actual Registry object, it is a stub, and you can't unexport those.
But unexporting the Registry and then calling unbind() doesn't make sense. Doing it the other way round makes a little sense, but not much.
And you also have to unexport your own remote object.
And creating a new remote object in a method that is trying to unexport the existing one doesn't make sense either.

android signalR hubconnection application negotiation failed with server

hi i'm new in android developing and i want to write an application which use signalR java-client. in first step i did the answer of this and here is my client code:
Platform.loadPlatformComponent(new AndroidPlatformComponent());
String host = "localhost";
HubConnection connection = new HubConnection( host);
HubProxy hub = connection.createHubProxy("HubConnectionAPI");
SignalRFuture<Void> awaitConnection = connection.start(new LongPollingTransport(connection.getLogger()));
try {
awaitConnection.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
hub.subscribe(this);
try {
hub.invoke("DisplayMessageAll", "message from android client").get();
System.out.println("sent!!!");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
and u can download the server code from here
i have following error with awaitConnection.get();
error:
W/System.err: java.util.concurrent.ExecutionException: microsoft.aspnet.signalr.client.transport.NegotiationException: There was a problem in the negotiation with the server
i also have this error:
Caused by: microsoft.aspnet.signalr.client.http.InvalidHttpStatusCodeException:Invalid status code: 404
can anyone please help me? i searched a lot but i didn't found anything helpful for me
EDIT:
clients can access the hub via this but how can i implement on android so my application can connect?
this is the log file on server:
2015-11-11 09:05:08 10.2.0.18 GET /signalr/negotiate clientProtocol=1.3&connectionData=%5B%7B%22name%22%3A%22hubconnectionapi%22%7D%5D 80 - 10.2.0.253 SignalR+(lang=Java;+os=android;+version=2.0) - 404 0 2 3
changed the String host = "localhost";
to String host = "localhost/signalr";
localhost didn't work for me, i had to deploy the asp.net web application on IIS, allow the port in Firewall inbound rules and put it in signalr config in android.. hope this helps someone... Cheers!

Android JDBC Connectivity problems

I am trying to connect to my website's MySQL database, and I have no knowledge of PHP so I decided to use JDBC. I followed some video tutorials (non JDBC) and I used their steps. I skipped the MAMP step though because I am not hosting the server off of my PC. It is being hosted locally because it is going to be a larger website.
So I have this code entered in my Login Activity (first screen you see):
Connection connection = null;
Statement statement = null;
String username = "username";
String password = "password";
String dbURL = "jdbc:mysql://216.26.176.52:3306/lifesizefoto";
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(dbURL, username, password);
statement = connection.createStatement();
System.out.println("Connected.");
} catch (ClassNotFoundException error) {
System.out.println("Cannot connect");
} catch (SQLException error) {
System.out.println("Error: " + error.getMessage());
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (connection != null) { try {connection.close();} catch (SQLException ignore) {} }
if (statement != null) { try {statement.close();} catch (SQLException ignore) {} }
}
I have tried many variations to the .getConnection() statement, but I can't figure it out. I have also contacted the website host and he took down all firewalls for my IP and even opened up a special port for the app.
When I run my app, I get this error:
01-09 18:59:32.769: I/System.out(14178): Error: Communications link failure
01-09 18:59:32.769: I/System.out(14178): The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
I would appreciate any help. Thank you in advanced!
Two thoughts:
It's unlikely that your web site's MySQL server is bound to an external interface - it's likely only listening on the localhost interface. Your hosting provider should be able to confirm / possibly fix that for you.
Trying to connect a mobile app directly to a server database is probably not going to work well in the long run - I'd suggest that you either figure out how to write a server-side app (for your mobile app to connect to) in PHP, or find another language that your host supports, and do it in that.

Categories

Resources