在安卓开发中,直接通过Socket连接数据库的场景较少见(通常通过HTTP/REST或JDBC连接),但某些特殊需求(如自定义协议、内网穿透等)可能需要直接操作Socket,以下是关键判断逻辑:
核心步骤 | 说明 |
---|---|
创建Socket对象 | 指定服务器IP和端口,尝试建立连接 |
设置超时时间 | 通过setSoTimeout() 避免长时间阻塞 |
发送心跳包/测试指令 | 发送简单请求(如SELECT 1 )验证连接有效性 |
捕获异常类型 | 根据IOException 、TimeoutException 等判断连接状态 |
关闭资源 | 无论成功或失败,均需关闭Socket释放资源 |
import java.io.OutputStream; import java.net.Socket; public class SocketDBChecker { public static boolean checkConnection(String host, int port, String testQuery) { Socket socket = new Socket(); try { // 1. 连接服务器(超时时间设为5秒) socket.connect(new InetSocketAddress(host, port), 5000); // 2. 发送测试指令(需符合数据库协议,此处假设自定义协议) OutputStream out = socket.getOutputStream(); out.write(testQuery.getBytes()); out.flush(); // 3. 接收响应(需根据协议解析,此处简化判断) // 读取返回结果是否包含预期关键字 byte[] buffer = new byte[1024]; int len = socket.getInputStream().read(buffer); return len > 0 && new String(buffer, 0, len).contains("OK"); } catch (IOException e) { // 连接失败或超时 return false; } finally { try { socket.close(); } catch (IOException ignored) {} } } }
异常类型 | 可能原因 | 处理建议 |
---|---|---|
UnknownHostException |
域名解析失败(如DNS配置错误) | 检查网络或更换DNS |
ConnectTimeoutException |
目标服务器无响应(端口关闭/防火墙拦截) | 确认服务器端口开放,检查防火墙规则 |
SocketTimeoutException |
数据传输超时(网络延迟高/服务器处理慢) | 延长超时时间或优化服务器性能 |
IOException |
通用IO错误(如服务器崩溃、网络中断) | 重试连接或提示用户检查网络 |
协议兼容性
直接通过Socket发送SQL语句需确保协议匹配(如MySQL协议需握手认证,PostgreSQL需Startup Message),推荐使用成熟库(如JDBC
)或自定义协议封装。
安全性风险
SSLSocket
加密通信。线程管理
网络操作需在子线程执行,避免阻塞主线程:
new Thread(() -> { boolean isConnected = SocketDBChecker.checkConnection("192.168.1.100", 3306, "SELECT 1"); runOnUiThread(() -> showResult(isConnected)); }).start();
解答:
MySQL使用自有协议,需完成以下步骤:
Handshake
认证包。Handshake
响应,获取盐值(salt
)。password_hash
)并发送认证包。COM_QUERY
指令执行SQL语句。MySQL Connector/J
库,内部已封装完整协议。解答:
| 对比维度 | Socket直连 | JDBC连接 |
|——————–|———————————–|———————————-|
| 协议层 | 需手动处理数据库协议(复杂) | 自动封装协议,只需关注SQL语句 |
| 安全性 | 需自行实现加密、认证 | 支持SSL、内置用户认证 |
| 开发成本 | 高(需处理细节) | 低(开箱即用) |
| 适用场景 | 自定义协议、特殊需求 | 标准数据库访问 |
建议优先使用JDBC或数据库官方驱动,除非有特殊