当前位置:首页 > 行业动态 > 正文

安卓实现与服务器tcp通信

权限配置

AndroidManifest.xml中添加网络权限:

<uses-permission android:name="android.permission.INTERNET" />

若需访问局域网,还需添加:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

网络操作线程处理

Android禁止在主线程执行网络IO操作,需通过以下方式处理:
| 方案 | 说明 |
|———————|———————————————————————-|
| Thread | 创建新线程执行Socket操作 |
| AsyncTask | 已过时但可用(API<30) |
| Handler+Thread | 通过消息机制更新UI |
| Kotlin Coroutine | 现代推荐方式(协程+withContext(Dispatchers.IO)) |
| WorkManager | 适合延迟/周期性任务 |

Socket通信核心代码

// 1. 创建Socket连接
Socket socket = new Socket();
SocketAddress serverAddress = new InetSocketAddress("192.168.1.100", 8888); // 替换为服务器IP和端口
socket.connect(serverAddress, 5000); // 设置5秒超时时间
// 2. 获取输入输出流
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
// 3. 发送数据
String message = "Hello Server";
outputStream.write(message.getBytes());
outputStream.flush();
// 4. 接收数据
byte[] buffer = new byte[1024];
int len = inputStream.read(buffer);
String response = new String(buffer, 0, len);
// 5. 关闭资源
outputStream.close();
inputStream.close();
socket.close();

完整示例(带异常处理)

public class TcpClient {
    private static final String SERVER_IP = "192.168.1.100"; // 服务器IP
    private static final int SERVER_PORT = 8888;            // 服务器端口
    private static final int TIMEOUT = 5000;               // 超时时间(ms)
    public static void startConnection() {
        new Thread(() -> {
            try {
                // 创建Socket并连接
                Socket socket = new Socket();
                socket.connect(new InetSocketAddress(SERVER_IP, SERVER_PORT), TIMEOUT);
                // 获取流对象
                OutputStream os = socket.getOutputStream();
                InputStream is = socket.getInputStream();
                // 发送数据
                String sendData = "Request Data";
                os.write(sendData.getBytes());
                os.flush();
                // 接收数据
                byte[] buffer = new byte[1024];
                int readLen = is.read(buffer);
                String receiveData = new String(buffer, 0, readLen);
                // 打印结果(实际应通过Handler更新UI)
                Log.d("TCP_CLIENT", "Received: " + receiveData);
                // 关闭资源
                is.close();
                os.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

本地测试服务器搭建

Python简易服务器(适合测试)

# 在PC端运行(需安装Python)
python -m http.server 8888 # HTTP服务器(非TCP)

Python TCP服务器示例

# tcp_server.py
import socket
HOST = '0.0.0.0'  # 监听所有接口
PORT = 8888      # 端口号
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    print(f"Server listening on {PORT}...")
    conn, addr = s.accept()
    with conn:
        print(f"Connected by {addr}")
        while True:
            data = conn.recv(1024)
            if not data:
                break
            print(f"Received: {data.decode()}")
            conn.sendall(b"Echo: " + data)  # 回显数据

使用Netcat工具(Linux/Mac)

# 在终端运行(模拟TCP服务器)
nc -l -p 8888   # 监听8888端口

常见问题及解决方案

问题现象 原因分析 解决方案
NetworkOnMainThreadException 主线程执行网络操作 移至子线程或使用异步框架
ECONNREFUSED 服务器未启动/IP/端口错误 检查服务器状态及配置信息
Permission denied 未声明INTERNET权限 添加<uses-permission>
数据接收不完整 未正确处理流结束或缓冲区大小不当 循环读取直到流结束
SSL握手失败 使用HTTPS但未配置证书 启用SSLSocket并加载证书

相关问题与解答

Q1:TCP通信与UDP通信有什么区别?何时选择TCP?
A:TCP(传输控制协议)提供可靠连接,保证数据顺序和完整性,适用于需要稳定传输的场景(如文件传输、即时通讯),UDP(用户数据报协议)无连接确认,速度快但不可靠,适用于实时性要求高且允许少量丢包的场景(如在线游戏、视频直播)。


Q2:如何实现Android与服务器的SSL加密通信?
A:需使用SSLSocket替代普通Socket,步骤如下:

  1. 服务器需配置SSL证书(自签名或CA签发)
  2. 客户端代码示例:
    // 创建SSLContext并信任所有证书(仅测试环境)
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustAllCerts, new SecureRandom());

// 创建SSLSocket
SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket();
sslSocket.connect(new InetSocketAddress(SERVER_IP, SERVER_PORT), TIMEOUT);


正式环境需验证服务器证书合法性,避免中间人攻击