需要与服务器建立“稳定”的TCP连接

时间:2011-01-16 17:08:45

标签: android

我需要与服务器建立“稳定”连接。

  1. 客户端每隔5(10,N)秒尝试连接一次服务器。

  2. 成功连接后,客户端会从服务器接收数据。

  3. 如果服务中断(例如服务器关闭),请转到步骤#1。

  4. 我如何测试:

    1. 我启动服务器

    2. 我启动客户端(以确保客户端从服务器获取数据)

    3. 我停止了服务器

    4. 我等待大约200次客户端尝试连接到服务器。

    5. 我重新启动服务器。

    6. 服务器发送数据,但客户端无法获取数据。 socket.connect(...)是成功的,但是 socket.getInputStream().read(byte[])不是Thread上的input.read(..)块。

      如果我取消注释这一行:

      //socket.setSoTimeout(500);
      

      然后input.read(..)会抛出TimeoutException

      但是服务器从客户端接收数据。

      我哪里错了? 感谢。

      部分客户端代码:

      private void initSocket() {
          try {
              if (socket == null || socket.isClosed() == true
                      || socket.isConnected() == false) {
                  socket = new Socket();
                  // socket.setSoTimeout(500);
                  InetSocketAddress socketAddress = new InetSocketAddress("192.168.1.3"
                        , 12344);
                  notifyDataListener(4);
                  socket.connect(socketAddress, 500);
                  notifyDataListener(5);
              }
          } catch (Throwable t) {
              System.err.println(t);
          }
      }
      
      private void closeSocket() {
          try {
              if (socket != null && socket.isClosed() == false) {
                  socket.close();
              }
          } catch (Throwable t) {
              System.err.println(t);
          }
      }
      
      private byte[] buffer = new byte[1024];
      
      public void run() {
          while (isActive) {
              try {
                  notifyDataListener(1);
                  initSocket();
                  InputStream input = socket.getInputStream();
                  int length = input.read(buffer);
                  if (length < 0) {
                      throw new EOFException("Was got -1");
                  }
                  notifyDataListener(2);
              } catch (Throwable t) {
                  closeSocket();
                  notifyDataListener(3);
                  try {
                      Thread.sleep(100);
                  } catch (InterruptedException ie) {
                  }
              }
          }
      }
      

      在J2SE上,相同的代码工作正常。许多错误尝试后连接修复。 看起来Android有限制套接字(FileDescriptior?),接受它们,但不会发布。

1 个答案:

答案 0 :(得分:0)

你的文件描述符可能用完了,我确定android的限制比典型的桌面配置要低得多,但具体的值会有所不同。

根据您对此进行编码的方式,套接字将一直挂起,直到其垃圾被收集,另外在某些平台上,操作系统级别的套接字不会立即关闭,而是会挂起一段时间来清理任何挂起的数据。

您应该做的第一件事是将socket.close()代码移动到finally {}语句,这将立即释放套接字,而不是等待垃圾回收。