【问题标题】:Android application is freezed - Socket ExceptionAndroid 应用程序被冻结 - 套接字异常
【发布时间】:2013-06-14 21:13:44
【问题描述】:

我制作了连接远程服务器并发送一些数据的安卓应用程序。 远程服务器是 Windows 应用程序。

连接方式:

private void ConnectToMonitor() {
    try {
        s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT);
    } catch (UnknownHostException e) {

        e.printStackTrace();
    } catch (IOException e) {

        e.printStackTrace();
    } finally {
        try {
            s.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

如果服务器在线,这将完美运行。应用程序正在发送数据,服务器正在接收。但是,如果服务器是离线的 android 应用程序。被阻止。我的问题是如何处理这个?如何在服务器宕机的情况下继续申请并避免错误?

【问题讨论】:

    标签: android sockets


    【解决方案1】:

    记得在 UIThread 之外调用它。 关注this 教程。在 android 中,所有连接都需要在 UIThread 之外进行管理,在我链接的教程中,您将找到将结果发布回 UI 的简单方法(处理程序、异步任务......)

    当然,我们不知道问题是否与仅具有给定代码的线程有关,但这是最常见的错误。

    【讨论】:

      【解决方案2】:

      首先记得设置socket超时

      mSocket.setSoTimeout(timeout); //in milliseconds
      

      但是,您可以通过套接字为连接和所有其他 I/O 操作指定不同的超时:

      private void connectToMonitor() {
          try {
              socket = new Socket();            
              InetAddress[] iNetAddress = InetAddress.getAllByName(SERVER_ADDRESS);
          SocketAddress address = new InetSocketAddress(iNetAddress[0], TCP_SERVER_PORT);
      
              socket.setSoTimeout(10000); //timeout for all other I/O operations, 10s for example
              socket.connect(address, 20000); //timeout for attempting connection, 20 s
          } catch (UnknownHostException e) {
      
              e.printStackTrace();
          } catch (IOException e) {
      
              e.printStackTrace();
          } finally {
              try {
                  socket.close();
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
          }
      }
      

      其次,在 Android 中,您应该在单独的线程中执行任何网络 I/O!

      例如,使用常规 Java 线程:

      String threadName = getClass().getName() + "::connect";     
          new Thread(new Runnable() {         
              @Override
              public void run() {
                  connectToMonitor();
              }
          }, threadName).start();
      

      【讨论】:

      • 抱歉,这个线程代码有问题。语法是否正常,因为语法编辑器显示错误..
      • @Josef 这个代码是正确的。你在哪里叫这个?尝试在您的活动的 onCreate() 或 onResume() 上使用它作为实验。看看它是否在那里工作。另请注意,您的方法名称是 ConnectToMonitor,实际上应该是 connectToMonitor()。
      • 现在它工作正常,它不再冻结应用程序了。现在我想检查服务器是否在线。如果没有尝试连接。为了实现这一点,我在 onCreate() 外部运行并通过按下按钮启动来启动线程。线程需要每 5 秒执行一次,因此代码如下所示: Runnable r = new Runnable() { @Override public void run() { while (serverConnection == true) { try { Thread.sleep(5000);连接监视器(); } catch (InterruptedException e) { e.printStackTrace(); }}}};但这不起作用
      • @Josef Hey Josef,这是一个完全不同的问题。如果没有看到更多代码,很难说。我建议你研究一下;如果你没有找到答案开始一个新的话题。我去看看。
      • 我只需要每隔 X 秒检查一次与服务器的连接。如果服务器关闭,则重新连接。我从 onCreate(...) 开始尝试使用 Timer 并每 3000 毫秒执行一次。什么都没发生。我的服务器应用程序是 Windows 桌面应用程序,它侦听端口 8890,只接收来自客户端的信息。如果服务器应用程序启动它工作正常,但如果我关闭连接并重新启动客户端应用程序(android 应用程序)不检查连接。只有第一次被凝视。
      【解决方案3】:

      您可以为套接字设置超时。使用Socket.setSoTimeout方法

      socket.setSoTimeout(timesinmilis);
      

      通过使用这个你的套接字将抛出一个套接字超时异常。你可以抓住它并做你想做的事

      【讨论】:

      • 我将超时设置为 5000 毫秒。 IOException 的 catch 块已经处理了套接字超时异常......但是如何在超时后继续应用程序?我想要实现的是当活动开始时,检查连接。如果没有连接正常继续应用程序。现在应用程序只给我等待或关闭应用程序的错误消息。
      • @Josef 在 Android 中,您应该在单独的线程上执行所有网络 I/O 操作!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-19
      • 1970-01-01
      • 2021-09-24
      • 1970-01-01
      • 2011-01-23
      • 1970-01-01
      相关资源
      最近更新 更多