You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 7.1.2设备同时使用以太网与WiFi通信的实现方案求助

Android 7.1.2 WiFi与以太网双网并行实现方案

问题根因

Android 7.1.2默认仅会为优先级最高的网络配置全局默认路由,并非系统层面禁止双网卡同时收发数据。当前代码无法实现双网并行的核心原因有两点:

  • 以太网绑定逻辑无效:网络回调中单独创建的Socket与ModbusClient内部使用的连接完全独立,绑定操作不会作用于实际的Modbus请求
  • 网络路由未做分流:若直接全局绑定进程到某一网卡,所有流量都会走该网卡,另一网卡的请求自然无法正常发送

前置权限配置

先在项目的AndroidManifest.xml中声明所需权限,以下权限不需要动态申请,清单文件中声明即可生效:

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

分步实现指引

1. 实现以太网状态监听

首先声明全局变量存储以太网的Network实例,注册系统网络回调实时获取以太网连接状态,不要在回调中创建无意义的独立Socket:

// 全局变量存储以太网网络实例
private Network mEthernetNetwork = null;

private final ConnectivityManager.NetworkCallback ethernetCallback = new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        super.onAvailable(network);
        mEthernetNetwork = network;
    }

    @Override
    public void onLost(Network network) {
        super.onLost(network);
        mEthernetNetwork = null;
    }
};

// 在页面onCreate中注册监听
ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest ethernetRequest = new NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
        .build();
connectivityManager.requestNetwork(ethernetRequest, ethernetCallback, new Handler(Looper.getMainLooper()));

// 不要忘记在页面onDestroy中注销回调
@Override
protected void onDestroy() {
    super.onDestroy();
    connectivityManager.unregisterNetworkCallback(ethernetCallback);
}

2. 改造Modbus请求逻辑,实现网络分流

新手优先选择临时进程绑定方案,不需要修改Modbus依赖库源码,改造成本最低:
在Modbus请求的工作线程中,连接控制器前临时将进程绑定到以太网,请求结束后无论成功失败,都切回原默认网络(WiFi),保证访问远端服务器的流量正常走WiFi。改造后的doInBackground逻辑如下:

@Override
protected String doInBackground(String... params) {
    ConnectivityManager cm = (ConnectivityManager) MyApp.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);
    // 先保存当前默认网络(即WiFi网络)
    Network defaultNetwork = cm.getActiveNetwork();
    try {
        if (mEthernetNetwork != null) {
            // 绑定当前进程所有流量到以太网
            cm.bindProcessToNetwork(mEthernetNetwork);
        }
        mClientReadAll.Connect();

        // 原有寄存器读取逻辑无需修改
        int[] registerBlock = mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_MODE.getRegister()- 1, 16);
        int[] wideRegisters = new int[] {
                Modbus.convertWideRegister(mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_ACTUAL_POSITION.getRegister() - 1, 2)),
                Modbus.convertWideRegister(mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_TARGET_POSITION.getRegister() - 1, 2)),
                Modbus.convertWideRegister(mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_ROM_DELTA.getRegister() - 1, 2)),
                Modbus.convertWideRegister(mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_REWIND_ZERO.getRegister() - 1, 2))
        };
        int[] tensionRegister = mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_ACTUAL_TENSION.getRegister() - 1, 1);
        Modbus.updateAllRegisters(registerBlock, wideRegisters, tensionRegister);

    } catch (Exception e) {
        Log.i(TAG, "Modbus读寄存器异常: " + e.getMessage());
        e.printStackTrace();
    } finally {
        try {
            mClientReadAll.Disconnect();
        } catch (Exception e) {
            Log.i(TAG, "Modbus断开连接异常");
        }
        // 必须在finally块中切回原默认网络,避免其他请求被路由到以太网
        cm.bindProcessToNetwork(defaultNetwork);
    }
    return null;
}

bindProcessToNetwork是Android 6.0及以上版本开放的官方公开API,7.1.2系统完全支持,不需要root权限,也不需要修改系统源码,是应用层实现双网分流最稳定的方案。

3. 进阶优化方案(稳定性更高)

如果使用的Modbus开源库支持自定义SocketFactory,可以直接传入mEthernetNetwork.getSocketFactory()创建Modbus连接,这样Modbus流量从Socket创建阶段就固定走以太网,不需要反复绑定/解绑进程网络,完全不会干扰WiFi请求的正常路由,适合长期稳定运行的场景。如果当前使用的Modbus库不支持自定义SocketFactory,替换为j2mod等主流开源Modbus库即可。

注意事项

  • 提前在平板系统设置中为以太网配置静态IP,确保以太网和WiFi处于不同网段,例如WiFi网段为192.168.1.x时,以太网可配置为192.168.2.x,避免路由冲突
  • 网络切回操作必须放在finally块中执行,防止Modbus请求抛出异常时,进程持续绑定在以太网上导致服务器请求失败
  • 不要在onAvailable回调中全局绑定进程到以太网后不做切回,否则所有App流量都会走以太网,WiFi请求将无法正常发送
  • 测试阶段可先将Modbus轮询间隔调整为500ms,验证双网通信稳定后再根据需求调整轮询频率

内容的提问来源于stack exchange,提问作者Jake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 05:21:46