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

Android客户端Socket无法接收Windows Java服务端数据求助

家庭WiFi下客户端-服务端通信异常排查建议

我在家庭WiFi环境下严格按规范实现客户端-服务端通信,但一直出现异常,急需技术建议。已经在Android Manifest中配置了INTERNET、ACCESS_NETWORK_STATE权限(还有MANAGE_EXTERNAL...权限,不过这个和当前问题不直接相关),怀疑是不是ISP的问题?

Java服务端代码

try {
    FileInputStream fIS = new FileInputStream(file);
    fIS.read(array, 0, array.length);
    Socket client = serverSocket.accept();
    if (!(client.getInetAddress().getHostAddress().equals("192.168.1.2"))) client.close();
        System.out.println(client.getInetAddress().getHostAddress() + " HAS CONNECTED, PORT "
            + client.getPort());
    if (client.isOutputShutdown()) {
        System.out.println("CLIENT SOCKET HAS BEEN SHUT!!!!!!");
        return;
    }
    OutputStream clientOut = client.getOutputStream();
    System.out.println("SENDING FILE CHUNKS...");
    System.out.println("0000000000000000");
    clientOut.write(array, 0, array.length);
    clientOut.flush();
    System.out.println("111111111111111111");
    client.close();
    System.out.println("333333333333333333");
    System.out.println("FINISHED!");
    }
catch(SocketException se){
        System.err.println(se.getMessage());
        se.printStackTrace();
    }
catch(FileNotFoundException ex){
        System.err.println(ex.getMessage());
    }
catch(IOException ex){
        System.err.println(ex.getMessage());
    }

Android客户端代码

try {
    clientSocket = new Socket("192.168.1.4",65001,thisLocalAddr,64999);
    clientSocket.setSoTimeout(15000);
    array = new byte[13574867];
    InputStream realIS =  clientSocket.getInputStream();
    if (clientSocket.isInputShutdown()) return;
    realIS.read(array,0,array.length);
    fiOS = new FileOutputStream(Environment.getExternalStorageDirectory() +
            "/Share/file.pdf");
    fiOS.write(array,0, array.length);

    realIS.close();
    clientSocket.close();
    fiOS.close();
}
catch (SocketException se) {
      Log.e("MainActivity ", se.getStackTrace().toString());

}
catch (NumberFormatException nfn) {
    Log.d("MainActivity", nfn.getStackTrace().toString());}
catch (UnknownHostException uhe) {
    Log.d("MainActivity", "Unknown Host Exception");
    Log.d("FileReceiver: ","dumbo =  " + dumbo.length()) ;
}

控制台输出

192.168.1.2 HAS CONNECTED, PORT 64999
SENDING FILE CHUNKS...
0000000000000000
Connection reset by peer
java.net.SocketException: Connection reset by peer
    at java.base/sun.nio.ch.SocketDispatcher.write0(Native Method)
    at java.base/sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:54)
    at java.base/sun.nio.ch.NioSocketImpl.tryWrite(NioSocketImpl.java:394)
    at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:410)
    at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:440)
    at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:819)
    at java.base/java.net.Socket$SocketOutputStream.implWrite(Socket.java:1223)
    at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1210)
    at Main.sendFile(Main.java:53)
    at Main.main(Main.java:15)

问题排查与解决建议

  1. 排除ISP影响:家庭WiFi内设备通信走局域网,不经过ISP骨干网,所以该异常和ISP无关,优先排查代码和本地网络配置。

  2. 修复服务端核心问题

    • IP校验逻辑漏洞:当前代码在关闭非指定IP的客户端Socket后,没有终止后续流程,会导致对已关闭的Socket执行写入操作,直接触发连接重置。修改为:
      if (!(client.getInetAddress().getHostAddress().equals("192.168.1.2"))) {
          client.close();
          return; // 终止后续代码执行
      }
      
    • 文件读取不完整:fIS.read(array, 0, array.length)无法保证一次性读满整个数组,大文件会出现数据截断,改成循环读取:
      int bytesRead;
      while ((bytesRead = fIS.read(array)) != -1) {
          clientOut.write(array, 0, bytesRead);
      }
      clientOut.flush();
      
    • 资源自动回收:用try-with-resources语法自动关闭流和Socket,避免资源泄漏:
      try (Socket client = serverSocket.accept();
           OutputStream clientOut = client.getOutputStream();
           FileInputStream fIS = new FileInputStream(file)) {
          // 业务逻辑代码
      } catch (Exception e) {
          e.printStackTrace();
      }
      
  3. 修复客户端核心问题

    • 移除固定本地端口:指定固定本地端口64999可能导致端口冲突,让系统自动分配端口即可:
      clientSocket = new Socket("192.168.1.4",65001);
      
    • 处理实际读取字节数:realIS.read(array)返回实际读取的字节数,直接写入整个数组会导致文件冗余,修改为:
      int bytesRead = realIS.read(array,0,array.length);
      if (bytesRead > 0) {
          fiOS.write(array,0, bytesRead);
      }
      
    • 完善异常日志:SocketException只打印栈轨迹字符串无法定位问题,改成打印完整异常信息:
      Log.e("MainActivity ", se.getMessage(), se);
      
  4. 本地网络排查点

    • 关闭路由器的AP隔离功能:部分路由器默认开启该功能,会阻止局域网内设备互相通信
    • 检查Android设备的后台网络权限:部分国产ROM会限制后台App的网络访问,确保你的App在后台能正常联网
    • 测试小文件传输:先尝试传输几KB的小文件,排除大文件传输时的超时或缓冲区问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 13:18:20