Android端Java Socket通过AppSocket/JetDirect获取打印机9100端口反馈失败求助
Android下Java Socket连接打印机9100端口的问题解决
为什么会报Connection Reset?
大概率是这几个原因:
- PJL命令格式错误:打印机仅识别以
\r\n(回车换行)结尾的命令,若只写\n,打印机无法识别会直接断开连接。 - 流处理不规范:发送命令后未flush输出流,导致数据卡在缓冲区未发送;或是刚发完命令就关闭Socket,打印机来不及回应。
- Android权限缺失:Android 9及以上默认禁止明文网络请求,9100端口为明文通信,未配置权限会导致连接失败。
- 读取逻辑问题:未设置Socket超时,或输入流读取方式错误,导致连接被强制重置。
正确实现方式
1. 配置Android权限
在AndroidManifest.xml中添加必要权限:
<uses-permission android:name="android.permission.INTERNET" /> <application ... android:usesCleartextTraffic="true"> <!-- Android 9+ 必须配置,否则明文连接会被拦截 --> </application>
2. 严格遵循PJL命令格式
@PJL INFO ID必须以\r\n结尾,完整命令字符串为"@PJL INFO ID\r\n"。
3. 完整示例代码
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; import java.net.SocketTimeoutException; public class PrinterHelper { private static final int PRINTER_PORT = 9100; private static final int SOCKET_TIMEOUT = 5000; // 设置5秒超时,避免无限等待 public static String getPrinterId(String printerIp) throws IOException { Socket socket = null; OutputStreamWriter output = null; BufferedReader input = null; StringBuilder result = new StringBuilder(); try { // 创建Socket并设置超时 socket = new Socket(printerIp, PRINTER_PORT); socket.setSoTimeout(SOCKET_TIMEOUT); // 发送PJL命令 output = new OutputStreamWriter(socket.getOutputStream(), "UTF-8"); output.write("@PJL INFO ID\r\n"); output.flush(); // 强制刷新缓冲区,确保命令完整发送 // 读取打印机返回内容 input = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")); String line; try { // 循环读取直到流结束,超时代表数据已全部返回 while ((line = input.readLine()) != null) { result.append(line).append("\n"); } } catch (SocketTimeoutException e) { // 该异常属于正常情况:多数打印机发送完数据不会主动关闭流 } return result.toString().trim(); } finally { // 按顺序关闭资源:先关闭输入输出流,再关闭Socket if (input != null) { try { input.close(); } catch (IOException e) { e.printStackTrace(); } } if (output != null) { try { output.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
4. 额外注意事项
- 避免主线程执行网络操作:Android禁止在主线程进行网络请求,需将上述代码放在子线程、Coroutine或AsyncTask中执行。
- 用nc验证命令有效性:可通过
echo -e "@PJL INFO ID\r\n" | nc 打印机IP 9100再次确认命令格式,能正常返回结果则说明命令无问题。 - 其他排查方向:若仍报错,检查打印机9100端口是否开启、Android设备能否ping通打印机、是否有防火墙拦截两者的连接。
内容的提问来源于stack exchange,提问作者Aries
相关产品推荐
相关产品推荐

