Android客户端无法接收Python服务端返回数据,求问题排查方案
问题修复方案
核心故障原因
- 换行符匹配失败:Android端使用
BufferedReader.readLine()读取服务端响应,该方法仅在读取到换行符\n、回车符\r或输入流关闭时才会返回结果。但Python服务端返回的内容是不带任何换行标识的"K",导致readLine()一直处于阻塞状态,无法拿到返回值。 - UI操作违规:
Toast属于UI控件,禁止在工作线程中调用。你当前将Toast逻辑写在AsyncTask的doInBackground方法中,本身就会触发线程异常,且代码遗漏了.show()调用,就算拿到响应也无法弹出提示。 - 服务端逻辑阻塞:Python服务端发送响应后没有主动关闭连接,也没有输出结束标识,同时后续仍在阻塞等待客户端发送新数据,进一步导致Android端输入流读取超时。
修复后的代码
Android端
// 修改AsyncTask泛型,第三个参数改为String用来返回响应结果 class MyTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... voids) { StringBuilder response = new StringBuilder(); try { Log.d("ORI", "1- before connect"); sock = new Socket(LOCAL_HOST, PORT); Log.d("ORI", "2 - after connect" ); prWriter = new PrintWriter(sock.getOutputStream()); prWriter.write(msg); prWriter.flush(); BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream())); String line; while ((line = in.readLine()) != null) { response.append(line); } sock.close(); } catch (IOException e) { e.printStackTrace(); } return response.toString(); } // 新增onPostExecute方法,在主线程处理UI操作 @Override protected void onPostExecute(String result) { super.onPostExecute(result); Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show(); } }
Python服务端
import socket server_sock = socket.socket() server_sock.bind(("0.0.0.0", 5024)) server_sock.listen(1) client, addr = server_sock.accept() print(addr[0]) flag = False while True: try: data = client.recv(1024).decode() except Exception as e: print(str(e)) break else: if not flag: if data == '': pass print(data) try: # 响应内容末尾添加换行符匹配Android端readLine规则 client.send("K\n".encode()) except Exception as e: print(e) else: print("OK") flag = True # 单次通信结束后关闭客户端连接,触发Android端输入流结束 client.close() break server_sock.close()
内容的提问来源于stack exchange,提问作者Ori Bergman
相关产品推荐
相关产品推荐

