我目前正在为Android编写客户端软件,该软件将反复向服务器发送请求。

由于我认为每次发出请求时都保持重新连接套接字是一种浪费,因此我尝试开发一种方法,在该方法中,只要套接字处于活动状态且已失效,就可以使用该套接字,将尝试进行一次重新建立联系的尝试。

这是我当前的解决方案:

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;
        }


    }


}


这个想法是所有ioexceptions都会被调用someRequest方法的外部代码捕获,但是显然这意味着我的Foo类无法知道套接字需要重新连接!

我唯一能想到的解决方案是在someRequest中捕获异常,信号表明套接字已死并重新抛出该异常,但是,由于我加载了someRequest类型的方法,因此这似乎不是一个干净的解决方案。

谢谢。

最佳答案

重新抛出异常是可能的最干净的解决方案,并且它是非常标准的:这意味着您考虑了错误,但无法处理。

请小心抛出准确捕获的异常,以免丢失调试信息,这可以通过简单的方法完成

catch(IOException ioe) {
  throw ioe;
}


您还可以将异常包装到您自己的异常中(FooError或FooException),这样,如果您有多种导致异常的原因,则调用接口只需要知道一种异常并可以使用非常容易(如果使用的是基本处理程序而不考虑堆栈跟踪)。

catch(IOException ioe) {
  throw new FooError(ioe);
}


然后,您可以通过执行ioe来访问原始异常thrownFooError.getCause(),这样您仍然拥有所需的所有调试信息,并且具有访问它的良好界面。所有这些都无需消耗更多资源。

希望能有所帮助。

09-10 08:35
查看更多