使用org.apache.commons.net.telnet。*与android的问题

时间:2010-01-07 10:21:50

标签: java android

我在Android应用程序中使用org.apache.commons.net.telnet.*库时出现问题,我希望有人可以帮助我。

我已经实现了一个使用telnet与远程服务器通信的应用程序,一切正常。我遇到的问题是当我调用TelnetClient.disconnect()时方法没有返回。在运行测试用例时调用该方法(意思是没有Android,只需通过Eclipse),它会立即返回,但在Android上有些东西搞砸了。我的测试用例看起来像:

TelnetClient telnet = new TelnetClient();
telnet.connect(ipAddress, port); 
telnet.disconnect(); //HERE

有人可以告诉我为什么会这样吗?

如果我从连接的telnet对象获得InputStream并且在调用disconnect之后从telnet服务器发送了一些信息,则可能导致该方法返回并关闭通过调用{创建的comm线程{1}},这让我觉得某处有某种类型或锁定?

Dalvik VM或Android操作系统与我的Java VM和XP机器之间的根本区别是什么导致这种行为?

感谢您的帮助,下面的堆栈跟踪!

我有ANR出现时由.connect(..)创建的comm线程的堆栈跟踪(由于断开连接调用无限期挂起)。

TelnetClient.connect()

还来自调用"Thread-15" daemon prio=6 tid=17 NATIVE | group="main" sCount=1 dsCount=0 s=N obj=0x43812d90 self=0x1be528 | sysTid=1403 nice=-2 sched=0/0 handle=2703408 at org.apache.harmony.luni.platform.OSNetworkSystem.receiveStreamImpl(Native Method) at org.apache.harmony.luni.platform.OSNetworkSystem.receiveStream(OSNetworkSystem.java:236) at org.apache.harmony.luni.net.PlainSocketImpl.read(PlainSocketImpl.java:550) at org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:87) at org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:67) at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:177) at java.io.BufferedInputStream.read(BufferedInputStream.java:259) at java.io.PushbackInputStream.read(PushbackInputStream.java:160) at org.apache.commons.net.io.FromNetASCIIInputStream._read(FromNetASCIIInputStream.java:77) at org.apache.commons.net.io.FromNetASCIIInputStream.read(FromNetASCIIInputStream.java:175) at org.apache.commons.net.io.FromNetASCIIInputStream.read(FromNetASCIIInputStream.java:138) at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:177) at java.io.BufferedInputStream.read(BufferedInputStream.java:259) at org.apache.commons.net.telnet.TelnetInputStream._read(TelnetInputStream.java:122) at org.apache.commons.net.telnet.TelnetInputStream.run(TelnetInputStream.java:564) at java.lang.Thread.run(Thread.java:1060) 的线程(我的测试用例只在主线程上):

.disconnect()

更新

如果我明确地关闭输出和输入流(javadoc说不要做),而是调用DALVIK THREADS: "main" prio=5 tid=3 MONITOR | group="main" sCount=1 dsCount=0 s=N obj=0x4001ab08 self=0xbc60 | sysTid=1390 nice=0 sched=0/0 handle=-1343996920 at java.io.BufferedInputStream.close(BufferedInputStream.java:~166) at org.apache.commons.net.telnet.TelnetInputStream.close(TelnetInputStream.java:535) at java.io.FilterInputStream.close(FilterInputStream.java:81) at java.io.BufferedInputStream.close(BufferedInputStream.java:167) at couk.mypackage.comm.TelnetClient.closeTelnet(IGSTelnetClient.java:441) at couk.myoackage.comm.Translator$1.handleMessage(IGSTranslator.java:65) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:123) at android.app.ActivityThread.main(ActivityThread.java:4203) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549) at dalvik.system.NativeStart.main(Native Method) ,那么我可以关闭连接,即

disconnect()

我很困惑!

1 个答案:

答案 0 :(得分:1)

TelentClient extends TelnetTelnet extends SocketClient。如果您看到这些类,它将创建VT100连接。请参阅以下TelnetClient.java的代码。

 public TelnetClient() {
   /* TERMINAL-TYPE option (start)*/
   super ("VT100");
   /* TERMINAL-TYPE option (end)*/
   __input = null;
   __output = null;
 }

现在将创建超类。请参阅Telnet.java class。

中的代码
Telnet() {
      setDefaultPort(DEFAULT_PORT);
      _doResponse = new int[TelnetOption.MAX_OPTION_VALUE + 1];
      _willResponse = new int[TelnetOption.MAX_OPTION_VALUE + 1];
      _options = new int[TelnetOption.MAX_OPTION_VALUE + 1];
      optionHandlers = new TelnetOptionHandler[TelnetOption.MAX_OPTION_VALUE + 1];
}

DEFAULT_PORT此处为23

现在,请参阅connect中的SocketClient.java方法。

        public void connect(InetAddress host, int port)
                throws SocketException, IOException {
            _socket_ = _socketFactory_.createSocket(host, port);
            _connectAction_();
        }

这是使用Socket创建一个新的DefaultSocketFactory,它是指定主机和端口的TCP套接字。在connectAction方法中,它设置新套接字的超时。

现在,当我们调用disconnect时,它首先尝试关闭套接字。

public void disconnect() throws IOException {
            _socket_.close();
            _input_.close();
            _output_.close();
            _socket_ = null;
            _input_ = null;
            _output_ = null;
            _isConnected_ = false;
        }

因为您可以直接关闭Streams,所以套接字本身似乎存在问题。

这将是一个TCP套接字,我不知道Android如何使用TCP。你能检查一下吗?因为这种方法正在关闭3个私人成员。 OR可能是套接字已经关闭,因此无法再次关闭它?

希望这有帮助。

感谢。