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)
问题排查与解决建议
排除ISP影响:家庭WiFi内设备通信走局域网,不经过ISP骨干网,所以该异常和ISP无关,优先排查代码和本地网络配置。
修复服务端核心问题
- 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(); }
- IP校验逻辑漏洞:当前代码在关闭非指定IP的客户端Socket后,没有终止后续流程,会导致对已关闭的Socket执行写入操作,直接触发连接重置。修改为:
修复客户端核心问题
- 移除固定本地端口:指定固定本地端口
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);
- 移除固定本地端口:指定固定本地端口
本地网络排查点
- 关闭路由器的AP隔离功能:部分路由器默认开启该功能,会阻止局域网内设备互相通信
- 检查Android设备的后台网络权限:部分国产ROM会限制后台App的网络访问,确保你的App在后台能正常联网
- 测试小文件传输:先尝试传输几KB的小文件,排除大文件传输时的超时或缓冲区问题
内容的提问来源于stack exchange,提问作者Huang
相关产品推荐
相关产品推荐

