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

线程中无法连接打印机:WiFi打印服务器开发及多行打印求助

Hey Jack, let's dig into why your persistent printer server isn't working as expected when printing from your ArrayList—even though single-line prints work and your IP/port checks out. I've seen similar issues with network printers, so here are the most likely fixes and code adjustments to get this sorted:

1. Fix Connection Persistence (The #1 Culprit)

Single-line prints work because you're opening/closing the socket quickly, but looping through an ArrayList might be causing connection flakiness if you're reinitializing the socket/stream on every print. Network printers hate frequent connect/disconnect cycles.

Solution: Initialize your printer connection once (outside the loop) and reuse the same socket/output stream for all prints. Only close it when your server shuts down.

2. Ensure Correct Line Endings & Printer Commands

Many network printers (especially thermal ones) require specific line endings (like \r\n instead of just \n) or a final "print trigger" command to flush the buffer. Single-line prints might accidentally work, but multi-line needs explicit handling.

3. Avoid Blocking the Listener Thread

If your server is handling print requests in the same thread as it listens for new connections, it'll freeze up during long print jobs. Use a thread pool to offload printing tasks.


Modified MyPrinter Class (Fixed for Persistent Printing)

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.List;

public class MyPrinter {
    private Socket printerSocket;
    private OutputStream outputStream;
    private final String printerIp;
    private final int printerPort;

    // Initialize connection once on startup
    public MyPrinter(String ip, int port) throws IOException {
        this.printerIp = ip;
        this.printerPort = port;
        reconnect(); // Establish initial connection
    }

    // Helper to reconnect if connection drops
    private void reconnect() throws IOException {
        if (printerSocket != null && !printerSocket.isClosed()) {
            closeResources();
        }
        printerSocket = new Socket(printerIp, printerPort);
        printerSocket.setSoTimeout(0); // Disable timeout for long-lived connections
        outputStream = printerSocket.getOutputStream();
    }

    // Print all lines from your ArrayList
    public void printProducts(List<Product> products) throws IOException {
        // Check if connection is still alive before printing
        if (printerSocket.isClosed() || !printerSocket.isConnected()) {
            reconnect();
        }

        for (Product product : products) {
            // Use \r\n for proper line breaks (adjust based on your printer specs)
            String line = product.getProductInfo() + "\r\n";
            outputStream.write(line.getBytes());
            outputStream.flush(); // Force data to send immediately
        }

        // Send final print trigger (ESC/POS command for thermal printers; adjust for your model)
        outputStream.write("\x0C".getBytes()); // Form feed to eject paper
        outputStream.flush();
    }

    // Clean up resources on server shutdown
    public void closeResources() throws IOException {
        if (outputStream != null) outputStream.close();
        if (printerSocket != null) printerSocket.close();
    }
}

Modified Printer Server (Non-Blocking Listening)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class PrinterServer {
    private final ServerSocket serverSocket;
    private final MyPrinter printer;
    private final ExecutorService threadPool; // Handle multiple print requests at once

    public PrinterServer(int serverPort, String printerIp, int printerPort) throws IOException {
        serverSocket = new ServerSocket(serverPort);
        printer = new MyPrinter(printerIp, printerPort);
        threadPool = Executors.newFixedThreadPool(3); // Adjust pool size based on needs
        System.out.println("Printer server running on port " + serverPort);
    }

    public void startListening() {
        while (true) {
            try {
                Socket clientSocket = serverSocket.accept();
                // Offload print task to a separate thread so listener stays responsive
                threadPool.submit(() -> handlePrintRequest(clientSocket));
            } catch (IOException e) {
                System.err.println("Error accepting client connection: " + e.getMessage());
            }
        }
    }

    private void handlePrintRequest(Socket clientSocket) {
        try (
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)
        ) {
            // Assume client sends a "PRINT" command to trigger printing
            String request = in.readLine();
            if ("PRINT".equalsIgnoreCase(request)) {
                // Fetch your product ArrayList (replace with your actual data source)
                ArrayList<Product> productList = getProductData();
                printer.printProducts(productList);
                out.println("PRINT_SUCCESS");
            } else {
                out.println("INVALID_REQUEST");
            }
        } catch (IOException e) {
            System.err.println("Error handling print request: " + e.getMessage());
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                // Ignore close errors
            }
        }
    }

    // Replace this with your actual method to get product data
    private ArrayList<Product> getProductData() {
        ArrayList<Product> products = new ArrayList<>();
        products.add(new Product("Product 1: Wireless Headphones"));
        products.add(new Product("Product 2: Portable Charger"));
        products.add(new Product("Product 3: LED Desk Lamp"));
        return products;
    }

    public static void main(String[] args) throws IOException {
        // Replace with your printer IP/port and server port
        PrinterServer server = new PrinterServer(8080, "192.168.1.100", 9100);
        server.startListening();
    }
}

// Your Product class example
class Product {
    private final String productInfo;

    public Product(String info) {
        this.productInfo = info;
    }

    public String getProductInfo() {
        return productInfo;
    }
}

Quick Troubleshooting Steps

  • Test with Telnet: Run telnet [printer-ip] 9100, type multiple lines (ending with \r\n), then send \x0C—if this prints, your printer supports the commands above.
  • Check Network Traffic: Use Wireshark to capture traffic to your printer's IP/port. Verify that all lines are being sent correctly.
  • Printer Settings: Ensure your printer isn't set to "hold jobs" or has any network timeout settings enabled.

内容的提问来源于stack exchange,提问作者Jack Moe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:11:50