树莓派Zero Python服务器与Android Java应用Socket通信读取回复异常
解决Android Java读取树莓派Python服务器回复的跳过问题
看起来你的Android应用在发送指令后,读取服务器回复的环节出了问题——日志停在D/Sending data: Data has been send,说明读取逻辑要么阻塞了、要么抛出了未捕获的异常,直接终止了线程。我来帮你排查并修复这个问题:
1. 先捕获所有IO异常,找到问题根源
你的SendData Runnable里很可能没有对读取操作的异常进行捕获,导致一旦出现IO错误(比如服务器连接中断、流读取失败),线程会静默终止,不会打印任何错误日志。首先要给所有网络IO代码加上完整的try-catch,并打印异常栈:
private class SendData implements Runnable { private final String mCommand; public SendData(String command) { mCommand = command; } @Override public void run() { Socket socket = null; PrintWriter outWriter = null; BufferedReader inReader = null; try { // 替换成你的树莓派本地IP和服务器端口 socket = new Socket("192.168.1.100", 8000); outWriter = new PrintWriter(socket.getOutputStream(), true); inReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 发送指令 outWriter.println(mCommand); Log.d("Sending data", "Data has been sent"); // 注意拼写修正:sent而非send // -------------------------- // 核心:正确读取服务器回复 // -------------------------- String responseLine; // 方式1:如果Python服务器回复以换行结尾,用readLine()逐行读取 while ((responseLine = inReader.readLine()) != null) { Log.d("Server Response", "Received: " + responseLine); } // 方式2:如果服务器回复没有换行(比如二进制或连续文本),读取所有字节 /* ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inReader.read(buffer)) != -1) { byteBuffer.write(buffer, 0, bytesRead); } String fullResponse = byteBuffer.toString("UTF-8"); Log.d("Server Response", "Full response: " + fullResponse); */ } catch (IOException e) { // 关键:打印完整异常栈,这能帮你定位具体问题(比如连接超时、流关闭) Log.e("Network Error", "Failed to read server response", e); } finally { // 确保所有资源被正确关闭,避免内存泄漏 try { if (inReader != null) inReader.close(); if (outWriter != null) outWriter.close(); if (socket != null) socket.close(); } catch (IOException e) { Log.e("Resource Error", "Failed to close network resources", e); } } } }
2. 检查Python服务器的响应逻辑
如果Android端的读取逻辑没问题,那可能是树莓派的Python服务器没有正确发送响应或者关闭连接:
- 确保服务器发送响应后,要么关闭连接(让Android端的流检测到EOF),要么发送明确的结束标记(比如换行符,对应Android的
readLine())。 - 示例Python简易服务器代码(确保响应完整):
import socket HOST = '0.0.0.0' # 允许所有本地IP访问 PORT = 8000 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() print(f"Server running on {HOST}:{PORT}") while True: conn, addr = s.accept() with conn: print(f"Connected from {addr}") # 读取Android发送的指令 received_data = conn.recv(1024).decode('utf-8').strip() print(f"Received command: {received_data}") # 发送响应,末尾加换行符(对应Android的readLine()) conn.sendall(b"Command executed successfully\n") # 如果不需要保持连接,发送后可以主动关闭 # conn.close()
3. 几个容易踩的坑
- Android权限:确保你的
AndroidManifest.xml里添加了网络权限:<uses-permission android:name="android.permission.INTERNET" /> - 读取阻塞问题:如果Python服务器没有发送结束标记(比如换行),Android的
readLine()会一直阻塞,直到服务器关闭连接。这时候要么修改服务器添加换行,要么改用读取所有字节的方式。 - 线程提交问题:确保你的
SendDataRunnable是在子线程中执行的(比如用new Thread(new SendData("your_command")).start();),不要在主线程执行网络操作(会抛出NetworkOnMainThreadException)。
内容的提问来源于stack exchange,提问作者Mail Mailer
相关产品推荐
相关产品推荐

