Android端TCP Socket无法接收PC端数据问题求助
Android与PC TCP Socket通信问题排查与修复
我来帮你解决这两个头疼的问题,都是TCP Socket通信里常见的流处理和时序问题:
问题1:Android端无法接收PC端的回复
问题根源
你的Android代码在发送消息后立刻调用了dout.close(),这会直接关闭Socket的输出流,触发TCP的FIN报文。虽然此时Socket还能读取数据,但结合PC端的处理逻辑会出现时序错位:
- Android关闭输出流后,PC端的
br.readLine()才从阻塞中返回(因为之前没收到换行符,只能等流结束); - PC端发送完"OK"后立刻关闭了整个Socket;
- 此时Android端才开始调用
br.readLine(),但Socket已经被PC端关闭,导致br.readLine()返回null,而你的reply初始值是空字符串,最终展示的就是空内容。
同时还要注意:readLine()必须读取到换行符才会返回,两端的读写逻辑要配对。
修复代码
修改Android端doInBackground方法,调整流的关闭顺序,同时确保发送消息带换行符:
@Override protected Void doInBackground(Void... arg0) { Socket socket = null; BufferedWriter dout = null; BufferedReader br = null; try { socket = new Socket(dstAddress, dstPort); dout = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); br = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 发送消息时添加换行符,让PC端readLine()能正常返回 dout.write(msg); dout.newLine(); // 用系统默认换行符,比手动加"\n"更兼容 dout.flush(); // 先读取回复,再关闭流 reply = br.readLine(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 按"先打开后关闭"的顺序释放资源 try { if (br != null) br.close(); if (dout != null) dout.close(); if (socket != null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } return null; }
问题2:为什么移除dout.close()后,PC端只有程序终止时才收到消息
问题根源
PC端用BufferedReader.readLine()读取数据,这个方法的特性是:一直阻塞,直到读取到换行符,或者输入流结束。
你之前的Android代码只发送了msg本身,没有加换行符,PC端的readLine()就会一直等换行符。当你关闭dout时,会触发输入流结束的信号,PC端才会返回收到的内容;如果不关闭dout,PC端就会一直阻塞,直到Android程序终止、Socket被销毁,输入流才会结束。
修复方案
在Android端发送消息时,必须主动添加换行符,比如用上面代码里的dout.newLine(),或者直接在msg末尾拼接"\n"。这样PC端的readLine()就能立刻读取到完整的一行数据,不需要等流关闭就能继续处理回复。
内容的提问来源于stack exchange,提问作者Mahmoud Sameh
相关产品推荐
相关产品推荐

