Java如何通过Socket传递JSON对象?Android客户端读取阻塞求助
嘿,我来帮你搞定这个Socket传JSON的问题——你遇到的in.readLine()挂起其实是个很常见的坑,核心原因几乎都是服务器端没给换行符或者没刷新输出流,毕竟readLine()会一直卡着等换行符或者流关闭。咱们一步步来解决:
核心问题分析与解决方案
1. 先把服务器端的输出逻辑改对
BufferedReader.readLine()是严格按行读取的,它会一直阻塞直到读取到\n或者\r\n。如果你的服务器只发送了JSON字符串却没加换行,客户端就会永远等下去。另外,输出流的缓冲区如果不手动刷新,数据可能还留在内存里没真的发出去。
给你个服务器端的修改示例(假设你已经用Gson/Jackson生成了JSON字符串):
// 假设已经生成好JSON内容 String jsonMsg = "{\"content\": \"这是测试消息\"}"; // 获取客户端Socket的输出流,用BufferedWriter更方便处理换行 BufferedWriter outputWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); // 发送JSON + 换行符(关键!) outputWriter.write(jsonMsg); outputWriter.newLine(); // 给readLine()一个结束标记 outputWriter.flush(); // 强制把缓冲区的数据推出去,确保客户端能收到
2. 客户端的配套调整
Android端要记得必须在子线程里做网络操作(主线程会直接报错),另外读完数据后要正确关闭资源。调整后的客户端示例:
// 开启子线程执行网络请求 new Thread(() -> { try { // 替换成你的服务器IP和端口 Socket socket = new Socket("192.168.1.100", 8888); BufferedReader inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 现在能正常读到数据了,因为服务器发了换行符 String receivedJson = inputReader.readLine(); Log.d("SocketClient", "收到的JSON:" + receivedJson); // 这里可以解析JSON,比如用Gson或者Android自带的JSONObject // JSONObject jsonObj = new JSONObject(receivedJson); // String content = jsonObj.getString("content"); // 用完记得关闭资源 inputReader.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); Log.e("SocketClient", "网络出错:" + e.getMessage()); } }).start();
3. 进阶:更可靠的传输方式(可选)
如果你的JSON内容里可能包含换行符,或者想避免依赖换行符的限制,可以先发送JSON的长度,再发送内容,这样客户端能准确知道要读多少字节:
服务器端代码
String jsonMsg = "...你的JSON内容..."; DataOutputStream dataOut = new DataOutputStream(clientSocket.getOutputStream()); // 先发送JSON的字节长度(UTF-8编码) byte[] jsonBytes = jsonMsg.getBytes(StandardCharsets.UTF_8); dataOut.writeInt(jsonBytes.length); // 再发送JSON本身 dataOut.write(jsonBytes); dataOut.flush();
客户端代码
DataInputStream dataIn = new DataInputStream(socket.getInputStream()); // 先读长度 int jsonLength = dataIn.readInt(); // 再读对应长度的字节 byte[] jsonBytes = new byte[jsonLength]; dataIn.readFully(jsonBytes); // 转成字符串 String receivedJson = new String(jsonBytes, StandardCharsets.UTF_8);
最后排查几个常见坑
- 确认AndroidManifest里加了网络权限:
<uses-permission android:name="android.permission.INTERNET"/> - 服务器和客户端要在同一网络(比如局域网),或者服务器有公网IP且端口开放
- 服务器端的
ServerSocket.accept()是否成功获取到了客户端Socket?可以加日志确认 - 绝对不要在Android主线程里调用网络操作,会直接抛出
NetworkOnMainThreadException
内容的提问来源于stack exchange,提问作者jbg2408
相关产品推荐
相关产品推荐

