我正在尝试telnet到一个无根的Droid。我已启用INTERNET
权限,我通过WiFi将设备连接到与Mac OS X
框相同的网络上,并且我能够ping通我打开的端口。
在最初的实验中,我让它在一个有根的测试设备上工作,但我在UI Thread
而不是一个单独的线程上运行套接字处理程序。既然我在一个单独的线程上有网络模块,我就无法返回ServerSocket.accept ()
。它适用于谷歌版本的android(vanilla),但不适用于三星或索尼爱立信。
当我telnet到它时,我的尝试会超时,logcat
不会打印出任何异常或错误。
以下是我的代码的Google代码回购链接:Google-code Repository
我在一个单独的线程上运行ServerScoket.accept ()
,并在另一个线程上运行流处理器。我的设计评论(即我应该使用Handler
或AsyncTasks
)非常受欢迎。现在,为了向通过telnet接收的消息进行Toast,我使用Handler,通过Context
获取looper。
以下是我在非工作设备上的adb shell上运行netstat -n
时得到的结果:
~$ adb shell netstat -n
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:7777 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:7203 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:47609 127.0.0.1:7777 ESTABLISHED
tcp 0 0 127.0.0.1:7777 127.0.0.1:47609 ESTABLISHED
tcp 0 0 127.0.0.1:47610 127.0.0.1:7777 ESTABLISHED
tcp 0 0 127.0.0.1:7777 127.0.0.1:47610 ESTABLISHED
不同之处在于,在工作设备中,他们列出了一个IP,我的端口在状态LISTEN中打开。
更新:在<uses-permission android:name="INTERNET"/>
设置android_manifest
后,我尝试将端口号更改为689
。它不起作用;我得到了BindException
,说我可能缺少INTERNET权限。所以,我将其更改为1989
,然后我回到accept ()
工作的所有内容。我认为这是因为我在非root手机上运行它,而且我无法访问端口1024
及以下。
更新:我在Mac上运行了一个非常类似的程序,当我尝试使用分配给我的IP地址远程登录Mac时,它运行正常。当我尝试从另一台Mac上进行远程登录但它似乎无法连接时,它无法正常工作;连接会超时。但它确实在ad-hoc网络上工作。我还没有尝试使用机器人,但我会尽快更新。
更新:我设法让应用程序在3个独立的Droids上运行Vanilla(由谷歌发布的Android)。它适用于Nexus,Apanda A60(我的第一台设备; adb因某种原因不再检测它),以及定制的无品牌平板电脑。尽管如此,因为我已经提供了相当大的赏金,我计划直到最后才看到它。
如前所述,我的应用程序适用于Android的Vanilla版本,但不适用于修改版本。未能运行它的三部手机都是中档机型; 2 Samsung GT-i5503
s和Sony-Ericcson E16i
。
答案 0 :(得分:1)
查看adb shell中的netstat -n是否显示在accept()未返回时您选择的端口上实际侦听的任何内容。
同时意识到,当不以root用户身份运行时,您只能绑定非特权端口,其中默认的telnet端口不是示例。您的代码是否检查bind()是否成功?
更新:
由于代码可以在许多设备上运行(netstat -n可能会列出套接字),因此无法在主题设备上列出它应该仍然是一个焦点。 Java ServerSocket方法依赖于套接字工厂,它可以被覆盖以允许您对socket(),bind()和listen()进行不同的调用,从而指定更全面的细节,因此以这种方式尝试代码可能是有意义的。还有一个案例浮出水面,设备试图支持ipv6似乎导致了类似的问题,至少在其他java平台上创建低级别的套接字以指定ipv4似乎是一个很有希望的答案。
答案 1 :(得分:1)
您似乎遇到了网络问题,而不是代码问题。我使用了你的最新项目,正如预期的那样正在监听端口。
我将此添加到TelnetServer.setupServerSocket()
以确认一些信息:
Log.i("TelnetServer", "ServerSocket Address: " + this.server.getLocalSocketAddress());
try {
Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
while (en.hasMoreElements()) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
Log.i("TelnetServer", "Listen On: " + inetAddress.getHostAddress());
}
}
} catch (SocketException ex) {
Log.e("TelnetServer", ex.toString(), ex);
}
这将打印您的服务正在侦听的所有地址(如果它正在侦听0.0.0.0/0.0.0.0:xxx(在ServerSocket地址之后打印))。
您应该使用emulator
选项运行-tcpdump <file>
并提供此选项。它将确认正在尝试任何连接。我的预感是你的客户端无法访问服务器,这就是服务器没有收到连接的原因 - 而不是代码的问题。
请提供tcpdump文件,您的IP地址(客户端)和logcat输出(包括ServerSocket地址和Listen On语句)以供进一步分析。
答案 2 :(得分:0)
我知道你已经尝试了大部分的事情,你只需几步就可以在两个特定的设备上使用它。
只是一个想法,如果不是点到点,为什么不在地区网络中使用Muti-casting进行服务注册和发现。
这是java实现JmDNS
编辑:我应该说要检查与这两个设备的连接。