Reusing socket and detecting when it needs to be re-established
I'm currently writing client software for android that will repeatedly send request to a server.
Since I figured it would be a waste to keep reconnecting the socket everytime a request is made I tried developing a method in which the socket is used as long as it's active and when it's dead, one attempt will be be done to re-establish contact.
This is my current solution:
class Foo
{
private Socket socket=null;
private OutputStream outStream=null;
private InputStream inStream=null;
public void someRequest() throws UnknownHostException, IOException
{
setupConnection();
// Do stuff with outStream and inStream here
}
private void setupConnection() throws UnknownHostException, IOException
{
try
{
if(socket!=null && socket.isConnected() && !socket.isClosed()) return;
if(outStream!=null) outStream.close();
if(inStream!=null) inStream.close();
socket = new Socket(SERVER_NAME,SERVER_PORT);
outStream = socket.getOutputStream();
inStream = socket.getInputStream();
}
catch(IOException e)
{
socket = null;
throw e;
}
}
}
The idea is that all ioexcepti开发者_开发问答ons will be caught by the external code calling the someRequest method, however apparently this means that there is no way for my Foo class to know that the socket needs to reconnected!
The only solution I can come up with is catching the exception inside someRequest, signal that the socket is dead and rethrowing the exception, however since I have loads of someRequest type of methods this doesn't seem like a clean solution.
Thanks.
Rethrowing the exception is the cleanest solution possible, and it is quite standard: it means you take into account the error but you can not handle it.
Be careful to throw exactly the exception you catched so you don't loose debug informations, this can be done with a simple
catch(IOException ioe) {
throw ioe;
}
What you could do is also wrap this exception into your own kind of exception (FooError or FooException), this way if you have several causes of exceptions, the calling interface just need to know one kind of exception and can pinpoint the cause of error with much ease (in case it is using a basic handler not taking into account the stacktrace).
catch(IOException ioe) {
throw new FooError(ioe);
}
You can then access the original exception ioe
by doing thrownFooError.getCause()
this way you still have all the debugging information you need and have a nice interface to access it; all of this without consuming much more resources.
Hope it helped.
精彩评论