You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:13:18