使用Smack在Android真机上无法连接XMPP服务器的问题与解决
Android真机无法连接本地Openfire XMPP服务器问题
问题描述
使用Smack 4.4.6开发Android应用,连接本地部署的Openfire服务器时,模拟器运行正常,但真机出现以下超时错误:
org.jivesoftware.smack.SmackException$EndpointConnectionException: The following addresses failed: 'rfc6120 a/aaaa endpoint + [/192.168.1.186:5222] (/192.168.1.186:5222)' failed because: java.net.SocketTimeoutException: failed to connect to /192.168.1.186 (port 5222) from /192.168.1.197 (port 43530) after 30000ms.
连接核心代码如下:
String serverAddress = "192.168.1.186"; // Replace with your server's IP or hostname int serverPort = 5222; // Default XMPP port String username = "john@gmail.com"; String password = "john"; XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder() .setXmppDomain("ismail.org") .setHost(serverAddress) .setPort(serverPort) .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled) // You can adjust security settings as needed .build(); AbstractXMPPConnection connection = new XMPPTCPConnection(config); try { System.out.println("Trying to connect ...."); connection.connect(); System.out.println("Connected ..."); try { connection.login("john","john"); } catch (XMPPException | SmackException | IOException e) { e.printStackTrace(); } System.out.println("Logged in"); System.out.println("Start searching ....."); boolean alpha = exist("alpha", connection); System.out.println("The user exists or not: " + alpha); } catch (Exception e) { e.printStackTrace(); }
问题原因
模拟器与真机的网络访问权限差异导致:
- Android模拟器默认共享主机的网络栈,相当于本地进程访问服务器,Windows防火墙不会拦截这类请求。
- 真实设备通过局域网IP访问服务器,属于外部设备的入站请求,Windows防火墙默认会阻止未授权端口(如5222)的连接,从而触发超时错误。
规范解决方案
你自行配置的Windows防火墙入站规则是安全且合规的标准解决方式,无需关闭整个防火墙,具体步骤如下:
- 打开Windows 11的「Windows Defender防火墙」设置
- 左侧菜单栏点击「入站规则」
- 右侧点击「新建规则...」启动规则创建向导
- 规则类型选择「端口」,点击「下一步」
- 选择「TCP」协议,指定端口号
5222,点击「下一步」 - 选择「允许连接」,点击「下一步」
- 按需勾选网络配置文件(若仅在局域网使用,可只勾选「专用」;需要全网络支持则保持所有选项勾选),点击「下一步」
- 为规则命名(例如「允许XMPP 5222端口入站」),添加描述后点击「完成」
额外验证步骤
完成防火墙配置后,可通过以下步骤确保连接正常:
- 确认真机与服务器处于同一WiFi局域网,使用设备的终端工具ping服务器IP(
192.168.1.186),验证网络连通性 - 登录Openfire管理后台,检查「服务器信息」中的监听端口状态,确认5222端口已绑定局域网IP(而非仅
127.0.0.1) - 确保Android应用的
AndroidManifest.xml中已添加INTERNET权限:<uses-permission android:name="android.permission.INTERNET"/>
内容的提问来源于stack exchange,提问作者Ismail Bouaddi
相关产品推荐
相关产品推荐

