below is a static method for checking if the other side RMI server is online, i basically call a method that if it replies true it means the connection is on, if it does not reply and instead gives a exception it means something is wrong. Is there a better way to do it? And is there a better way to speed up the process? If there is connectivity it returns with the value fast, but if not it takes sometime.
public static boolean checkIfOnline(String ip,int port)
{
boolean online = false;
try {
InetAddress ipToConnect;
ipToConnect = InetAddress.getByName(ip);
Registry registry = LocateRegistry.getRegistry(ipToConnect.getHostAddress(),port);
ServerInterface rmiServer = (ServerInterface)registry.lookup("ServerImpl");
online = rmiServer.checkStudentServerOnline();
if(online)
{
System.out.println("Connected to "+ipToConnect);
}
} catch (RemoteException e) {
System.out.println(e.getMessage());
//e.printStackTrace();
return false;
} catch (NotBoundException e) {
System.out.println(e.getMessage());
//e.printStackTrace();
return false;
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return online;
}
The best way to test whether any resource is available is simply to try to use it. That will either succeed or fail, and the failure tells you that it wasn't available (or something else went wrong).
Any approach based on executing additional code beforehand is merely attempting to predict the future. It is liable to several problems, among them testing the wrong thing and changes of status between the test and the usage.
Related
I am running some logic in a Thread that depends on a HTTP connection to a remote server. Currently, the thread crashes, if the remote server is not running. I want to modify the logic so that the thread waits for the remote server to become available again.
Technically, the solution seems strait forward. Something along the lines of:
boolean reconnect = false;
while (!reconnect) {
try {
URL url = new URL("my.remoteserver.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
reconnect = true;
} catch (Exception ex) {
// wait a little, since remote server seems still down
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
// if thread was interrupted while waiting then terminate thread
break;
}
}
}
However, this solution is not very elegant. Also, the use case seems so generic that I suspect this could be done by some helpful library. Alas, I could not find any - who can tell me how to improve my solution?
I think this use case is simple enough to implement yourself instead of introducing additional dependencies. If you are concerned about your solution not being very elegant I suggest refactoring it into a couple of smaller methods, for example like this:
public void connect() {
try {
connectWithRetries();
} catch (InterruptedException e) {
// Continue execution
}
}
private void connectWithRetries() throws InterruptedException {
while (!tryConnect()) {
sleep();
}
}
private boolean tryConnect() {
try {
URL url = new URL("my.remoteserver.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
} catch (Exception e) {
return false;
}
return true;
}
private void sleep() throws InterruptedException {
Thread.sleep(5000);
}
Camel provides support for these kind of use-cases : http://camel.apache.org/http
However it is more a framework to build data-stream/event-driven applications so it might be a very big hammer to retry a connection to an http server. However, if it fits the application it is a great library/framework to move data around.
Very new to Java in particular, using the SimpleFTP library to send a file to a server.
It seems like any method call on a SimpleFTP object seems to require being inclosed in a try-catch. What is the proper way to disconnect from the server, then?
For example:
private void ftp()
{
int portNumber = 21;
SimpleFTP ftp = new SimpleFTP();
try
{
ftp.connect("serverAddress", portNumber, "userName", "password");
ftp.bin();
ftp.cwd("dir");
ftp.stor(new File("filePath"));
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
ftp.disconnect();
}
}
This does not compile, because of the content in fianlly's body. If I move it up to the try block and scrap the finally, it'll compile... But what if my app connects to the server, then throws an exception while doing the other tasks?
What you didn't mention is that the reason you're having a problem is that disconnect() is also declared to throw an IOException.
Looking at the source for SimpleFTP you find:
public synchronized void disconnect() throws IOException {
try {
sendLine("QUIT");
}
finally {
socket = null;
}
}
All it's doing is sending the QUIT command to the remote FTP server then just dropping the reference to the socket in its finally block. If that throws .... it means the socket is already dead, but since you're disconnecting you really don't care (If I'd written that client, i'd have caught and ignored the exception for that reason and not had it throw).
In your finally block just wrap it in it's own try/catch block and don't do anything in the catch block. Option B is just putting it in the try block. The only reason it's going to throw is if the socket is already disconnected and letting the SimpleFTP instance fall out of scope after an exception will clean things up just as well.
Surround the disconnect call with its' own try catch block...
finally
{
if (ftp != null) {
try {
ftp.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
I am implementing a Server/Client system using Java. the server listens for incoming connection from clients and after a client connects, the server creates a new socket and passes it to a new thread which will only be used for receiving data:
while (true){
clientSocket=serverSocket.accept();
new ClientReceiver(clientSocket,this.clientsManager).start();
}
the clientReceiver class is as follows:
public class ClientReceiver extends Thread {
private Socket clientSocket=null;
private Client client=null;
private ClientsManager clientsManager;
private ClientActionParser clientActionParser=new ClientActionParser();
ClientHandlerState clientHandlerState;
PrintWriter outputStream=null;
BufferedReader inputStream=null;
public ClientReceiver(Socket clientSocket, ClientsManager clientsManager){
this.clientSocket=clientSocket;
this.clientsManager=clientsManager;
this.setClientHandlerState(ClientHandlerState.Connected);
}
public void run(){
String actionString;
try{
//define output and input stream to client
outputStream =new PrintWriter(clientSocket.getOutputStream(),true);
inputStream = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//while client is connected read input to actionString
while((actionString=inputStream.readLine()) != null){
AbstractClientAction clientAction= this.clientActionParser.parse(actionString);
if(this.getClientHandlerState()==ClientHandlerState.Connected){
if(clientAction instanceof ClientLoginAction){
ClientLoginAction clientLoginAction=(ClientLoginAction) clientAction;
if(this.authenticate(clientLoginAction)){
}
else{
throw new AuthenticationException();
}
}
else{
throw new AuthenticationException();
}
}
}
if(this.getClientHandlerState()==ClientHandlerState.Authorized){
//receive other client actions: transfer barge ....
}
try {
Thread.sleep(400);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
catch(IOException e){
}
catch (AuthenticationException e) {
// TODO: handle exception
}
//clean up the resources
try{
outputStream.close();
inputStream.close();
clientSocket.close();
}
catch(Exception e){
}
}
private boolean authenticate(ClientLoginAction clientLoginAction){
//perform authentication. If authentication successful:
this.client=this.clientsManager.authenticateClient(clientLoginAction.getUsername(), clientLoginAction.getPassword());
if(this.client==null){
return false;
}
else{
ClientSender clientSender=new ClientSender(this.outputStream, this.client);
this.clientsManager.addClientSender(clientSender);
this.setClientHandlerState(ClientHandlerState.Authorized);
clientSender.start();
return true;
}
}
public ClientHandlerState getClientHandlerState(){
return this.clientHandlerState;
}
public void setClientHandlerState(ClientHandlerState clientHandlerState){
this.clientHandlerState=clientHandlerState;
}
after successful authentication in the receiver thread, a new thread is created for sending data to client and socket's outputStream is passed to the new thread.
the clientSender class contains a queue as a buffer which contains the data that should be sent to the client. here is class clientSender:
public class ClientSender extends Thread {
private Client client=null;
private final Log logger = LogFactory.getLog(getClass());
PrintWriter outputStream=null;
private Queue<String> clientEventsQueue= new LinkedList<String>();
public ClientSender(PrintWriter outputStream, Client client){
this.outputStream=outputStream;
this.client=client;
}
public void run(){
//System.out.println("ClientSender run method called.");
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(!this.clientEventsQueue.isEmpty()){
this.outputStream.println(this.clientEventsQueue.remove());
}
}
}
public Client getClient(){
return this.client;
}
public void insertClientEvent(String clientEvent){
this.clientEventsQueue.add(clientEvent);
}
whenever I want to send something to the client I use:
clientSender.insertClientEvent("some text");
the problem is that if I remove Thread.sleep(10) I will not receive anything in the client side. Since TCP sockets are blocking I think this should not happen. Is this normal or am I doing something wrong?
EDIT:
there is no "termination" for the sender thread. the server should send proper information to all clients whenever it receives an event from another system. so I think the best scenario is to stop the thread when there is no data to send and start it whenever there is. so I tried this in the clientSender class:
public void run(){
while(true){
if(this.clientEventsQueue.isEmpty()){
break;
}
else{
try {
this.outputStream.println(this.clientEventsQueue.take());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
but now the problem is when to start the thread? I tried starting it whenever I want to send data but as I expected it does not work properly and only sends the fist package:
clientSender.insertClientEvent(clientEvent.getEventString());
clientSender.start();
EDIT2
I came up with this idea. It is very simple and I think it consumes so much less CPU time.
while(true){
while(this.clientEventsQueue.isEmpty()){
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
this.outputStream.println(this.clientEventsQueue.take());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
as much as I tested it, it worked just fine. what do you think about it?
I see that you are using a LinkedList as a queue accessed by multiple threads and that you are doing a busy wait on it in the ClientSender.
This implementation is not thread safe and may cause problems like clientEvents posted on it not being made visible to the ClientSender thread, CPU being wasted etc.
You could use a BlockingQueue instead and call take() on it to block on the queue until an event is posted.
I also see that you are relying on sleep(400) to wait for the communication. That will also cause issues. The thread that is using the socket resource can close it when it's done, instead of this.
EDIT:
There are number of techniques to deal with terminating the thread. I think a "poison pill" will work well in this case. Basically you do:
String stuff = queue.take();
if (stuff == null) break;
and post null on the queue when you want to terminate it (doesn't have to be null, can be anything e.g. "terminate" etc.
EDIT2:
Your way of terminating won't work, as it will terminate immediately before anyone can post an event on it. Theoretically you could be spawning and then immediately killing the thread over and over etc. The easiest way to cope with this is to use a special message (aka "poison pill") for the termination condition.
As for having a thread only when there is an event, at that point I'd recommend using a thread pool. You could encapsulate the event sending into a Runnable, and hold the sockets in a Map. This is however quite complicated to implement and requires good understanding of multithreading to get it right. Multithreading is hard and can introduce severe headache when done wrong. Tbh I wouldn't recommend to try doing this without studying more about multithreaded programming.
EDIT3:
#user2355734: Polling the queue with an interval as you did is done by many people, but is discouraged. The take() method will in effect "sleep" and only wake up if there is something on the queue, so in theory by removing the "sleep" loop you should get even lower CPU usage and shorter latency. In general, you should try to avoid using "sleep" altogether in multithreaded code. It's rare that you genuinely need it and it's frequently a sign of broken/suboptimal code. As for tests, although they are useful it's hard or even pretty much impossible to guarantee correctness of multithreaded code through tests. Your code may run fine in your tests yet fail in production, under high load, under different environment etc. Therefore it's important to review the code and make sure it's theoretically correct.
Good day,
I am busy writing a networking class for an android application that is going to make use of the wireless tcp connection on the phone.
This class below is what i have coded so far. But when coding it i forgot about the multi- threading aspect of it.
Network class:
// Network Class That controls all the connecting, sending of data and recieving of data over the tcp protocol
public class Network {
// GLOBAL VARIABLE DELERATIONS
public Socket TCPSocket;
public OutputStream out;
public BufferedReader in;
public InetAddress serverAddr;
// Servers IP address
public String SERVERIP;
// Servers Port no.
public int SERVERPORT;
BufferedReader stdIn;
// Constructor
public Network() {
// Set The IP of the server
SERVERIP = "41.134.61.227";
// Define the port for the socket
SERVERPORT = 8020;
// Resolve the ip adress
try {
serverAddr = InetAddress.getByName(SERVERIP);
Log.i("IP Adress: ", "Has been resolved");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Connect to the server socket
*
* #return a boolean indicating if the connection was successful
*/
public boolean connect() {
// Create the Socket Connections
try {
Log.i("TCP is attempting to establish a connection", null);
TCPSocket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("TCP Connection error :", e.toString());
return false; // Returns if the connection was unsuccessful
}
Log.i("TCP Connection :", "Connected");
return true; // Returns if the connection was successful
}
/**
* Disconnect from the server socket: Method to Call once you are done with
* the network connection, Disconnects the socket from the server
*/
public void disconnect() {
try {
out.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} // Close the out Stream
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// stdIn.close();
try {
TCPSocket.close(); // Close the TCP Socket
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("TCP Connection :", "Disconnected");
}
/**
* Send: Function that will transmit data aver the tcp socket (network)
*
* #param data
* the packet in raw data form, recieves a byte array
* #return Returns a boolean if the transaction was successful.
*/
// Function that will transmit the data over the tcp socket.
public boolean send(byte[] data) {
try {
out.write(data); // Write the data to the outStream
out.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false; // Return false if the TCP Transmit failed or
// encounted an error
}
return false;
}
// Function that will return the data that has been recieved on the tcp
// connection from the server
/**
* Recieve: Function that recives data from the socket.
*
* #return
*/
public byte[] recieve() {
return null;
}
What do i need to do to convert my class to use threads?
Which parts of it need to run on their own thread?
I would think that only the receive needs it own thread? as the send is only run when you call it ?
Sorry for the noob question but this is my 1st attempt at writing a networking app without just coping some example code from the net.
I originally followed this tutorial: NETWORKING TUTORIAL and i didnt quite under stand their tcp class where they have run methods.
So to summarize my question, which particular parts, when networking need to but run on a different thread? Thanks
Thanks
I'd just run all the class on a different thread. So... how do you convert a class to use threads? I think that's the part that you actually don't feel sure about. It's quite easy though... it can be as simple as using the class from within a Thread like this:
new Thread(new Runnable(){
public void run() {
new Network().connect();
}
}).start();
This will run your code on a separate Thread, and you don't even have to modify the class. So... that said... let's talk about Android (that snippet of code above is pure Java, but that's only the tip of the iceberg).
On Android it is important to use threading in order to avoid blocking the UI; that can be done with snippets of code like the one above, but such approach could cause some problems. So you have to learn this rule: I will not change my UI from within an external Thread. So the question here is: "How the heck should I update my UI to reflect changes on my worker thread?".
There are quite few ways... on of the most populars is the AsyncTask class. It basically allows you to run background threads and offer ways to update the UI in a safe way. They are useful if you know the Activity won't be finished while the AsyncTask is running.
If you are running more long-term tasks, you better use a Service. There are fancy ways to run background threads on a service; but you can also do it by yourself.
Anything that could block should be run on a different thread. That would be any attempt to send data, receive data, or connect. On a server it would include accept.
All of your networking (receiving and sending) you want to run on a background thread such as in an AsynTask as it will block your UI thread. Have your Network class extends AsyncTask and implement the required methods shown in the docs.
Do all of your background tasks in doInBackground() then manipulate your results in onPostExecute()
Just came across a rather confusing exam question, and my lecturer is away on holidays, so I come to StackOverflow begging for help!
The question is as follows :
"Joe has his own JoeConnection class for making connections between his computer and other computers. The class provides the following constructor and instance methods :
JoeConnection( String address ): Make a connection with the URL address.
void writeLn( String text ) : Write text to the JoeConnection.
String readLn( ): Read a line of text from the JoeConnection.
void clode( ) : Close the JoeConnection.
Joe's connections regularly fail and this causes errors. Using proper exception handling, demonstrate how to use Joe's JoeConnection class to
make a JoeConnection with the URL http://students.chat.box
write "Hello world" to the JoeConnection
read in a string from the JoeConnection
close the connection.
The connection handling should provide as man details as possible about the cause of failure and print the stack trace which led to the failure.
I have no idea how to tackle this, but I assume it is something similar to this :
public class Test {
try {
JoeConnection connection = new JoeConnection(http://students.chat.box);
} catch {
connectionError e; printStacktrace();}
}
}
Can anyone please help me figure this out? Thanks a lot.
Without an indication of what exceptions are thrown and why, the only proper exception handling is no handling at all. Don't catch an exception if you don't know how to fix the problem that triggered it.
But the further instructions in your assignment introduce a different notion of "proper." You're supposed to print a stack trace. So catch the exception and print a stack trace. You were on the right track, but your syntax was wrong. Refer back to your textbook and lecture notes to remind yourself what the syntax is for catching exceptions (and for passing strings to functions, for that matter).
try {
JoeConnection connection = new JoeConnection("http://students.chat.box");
connection.writeLn("Hello world");
// etc
} catch (Exception e) {
e.printStackTrace();
}
"Proper exception handling" is a little vague. I agree with #Rob Kennedy's statement that no exception handling is appropriate unless you know why the exception is thrown and what should be done with it. Otherwise, the exception should be allowed to propagate. So, for example:
void foo(String address) throws JoeException {
JoeConnection connection = new JoeConnection(address);
try {
connection.writeLn("Hello World!");
} finally {
// Ensure the connection is closed when finished.
// This happens whether an exception occurs or not.
connection.close();
}
}
If you wanted to catch the exception just to print it, you could do something like this:
void foo(String address) throws JoeException {
try {
JoeConnection connection = new JoeConnection(address);
try {
connection.writeLn("Hello World!");
} finally {
connection.close();
}
} catch (JoeException e) {
e.printStackTrace();
// Don't know what to do about this; rethrow.
throw e;
}
}
There is a subtlety here that even experience Java programmers can miss, though. If an exception occurs while creating the connection, it doesn't need to be closed. If an exception occurs while writing to the connection, it does need to be closed; thus the finally clause. However, the act of closing can also throw an exception. If closing the connection throws an exception, only that exception will be thrown by the try statement. If the finally clause was reached as a result of the writeLn operation throwing an exception, the exception of the writeLn call will be effectively ignored. This is probably not what you want.
Instead, we can try something ugly like this:
void foo(String address) throws JoeException {
try {
JoeConnection connection = new JoeConnection(address);
boolean normalCompletion = false;
try {
connection.writeLn("Hello World!");
normalCompletion = true;
} finally {
if (normalCompletion) {
// The writeLn operation completed normally.
// Propagate an exception thrown by the close operation.
connection.close();
} else {
// The writeLn operation completed abruptly.
// Ignore an exception thrown by the close operation.
try {
connection.close();
} catch (JoeException e) {
/* empty */
}
}
}
} catch (JoeException e) {
e.printStackTrace();
// Don't know what to do about this; rethrow.
throw e;
}
}
This looks (and is) syntactically hideous, but it does show "proper" exception handling of a sort. The language enhancement from Project Coin should clean this up a bit.
For starters, I can help you out with the syntax of what you wrote:
try {
JoeConnection connection = new JoeConnection("http://students.chat.box");
}
catch (JoeConnectionException e) {
e.printStacktrace();
}
I took the liberty of changing the linebreaks and renaming 'connectionError' as JoeConnectionException which looks more conventional to me.
You'll have to do something similar for the readLn, writeLn, and close method calls since it said that the connection regularly fails (i.e. not just while connecting).
Cheers, good luck.
Catching an exception should look like:
try {
JoeConnection conn = new JoeConnection(url);
} catch (YourExceptionClassNameHere e) {
e.printStackTrace();
}
Also: if you want to use a literal String, make sure you include the quotations. (It should be "http://students.chat.box".)
It's good to have a finally as well:
public class Test {
try {
JoeConnection connection = new JoeConnection(http://students.chat.box);
}
catch(Exception e) {
e.printStacktrace();
}
finally {
if(connection != null) {
connection.close();
}
}
}
Typically you handle exceptions if you know what to do with them (this involves error-recovery logic or wrapping an exception and throwing it to a higher level).
Assuming that each method throws an exception, you could do something like this for "maximum detail":
public class Test {
JoeConnection connection = null;
try {
connection = new JoeConnection("http://students.chat.box");
...
...
}
catch(OpenException e) {
System.out.println("Error while opening connection");
e.printStacktrace();
}
catch(WriteException e) {
System.out.println("Error while writing to connection");
e.printStacktrace();
}
catch(ReadException e) {
System.out.println("Error while reading from connection");
e.printStacktrace();
}
finally {
if(connection != null) {
connection.close();
}
}
}