Setting up a network virtual printer is a great way to save print jobs as digital files automatically. Unlike a local virtual printer (like Microsoft Print to PDF), a network virtual printer runs as a network service. It listens on a socket port, accepts print jobs over TCP/IP, and can process requests from your local machine or any device on your local network.
This guide shows you how to write a Python-based network printer server on port 9100, configure Windows to connect to it as a network printer over TCP/IP, and automatically convert incoming PCL or PostScript streams into PDFs using VeryPDF SPL to PDF Converter.
Local Virtual Printer vs. Python Network Virtual Printer
It helps to understand why a network-based printer server is different from standard local virtual printers:
| Feature | Local Virtual Printer (e.g., Microsoft Print to PDF) | Python Network Virtual Printer (TCP/IP Server) |
|---|---|---|
| Connection Type | Local system hook / Virtual port | Standard TCP/IP Network Socket (Port 9100) |
| Network Access | Only usable on the local PC | Accessible from any PC, phone, or ERP system on the network |
| Data Reception | Handled internally by OS | Captures raw network packets directly using Python socket |
| Automation | Asks for file path via popup window | Runs headless in background and processes files automatically |
Why Build a Network Virtual Printer in Python?
Many legacy business systems, point-of-sale (POS) terminals, and enterprise software can only output data to a network printer over port 9100. They cannot interface with local printer drivers or interactive "Save As" prompts.
- Network Accessibility: Receive print requests from multiple client machines across your network.
- Automated Processing: Intercept incoming raw network print jobs and convert them immediately without user interaction.
- Legacy Compatibility: Give older network-only applications a seamless way to generate PDF files.
Step 1: Write the Python Network Virtual Printer Server
Network printers use the RAW network protocol on port 9100 (Standard JetDirect). The Python script below creates a TCP network server that listens on port 9100, receives network print streams, saves the raw stream, and triggers a PDF conversion.
Create a file named network_virtual_printer.py:
import datetime import os import socket import subprocess # Folders to store incoming network raw streams and output PDFs RAW_DIR = "incoming_raw" PDF_DIR = "output_pdf" VERYPDF_PATH = r"C:\VeryPDF\spl2pdf.exe" # Update to your spl2pdf.exe path for folder in [RAW_DIR, PDF_DIR]: if not os.path.exists(folder): os.makedirs(folder)
def convert_to_pdf(raw_file_path): filename = os.path.basename(raw_file_path) pdf_filename = os.path.splitext(filename)[0] + ".pdf" output_pdf_path = os.path.join(PDF_DIR, pdf_filename) # Call VeryPDF command line tool to convert print stream to PDF cmd = [VERYPDF_PATH, raw_file_path, output_pdf_path] try: subprocess.run(cmd, check=True) print(f"[SUCCESS] Converted to PDF: {output_pdf_path}") except Exception as e: print(f"[ERROR] Conversion failed: {e}")
def start_network_printer(): # Bind socket to listen as a network print server server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Use '127.0.0.1' for local loopback testing, or '0.0.0.0' to accept network prints from other devices server.bind(("127.0.0.1", 9100)) server.listen(5) print("[*] Python Network Virtual Printer is active on port 9100...") job_id = 0 try: while True: client, addr = server.accept() job_id += 1 timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") raw_path = os.path.join(RAW_DIR, f"network_job_{timestamp}_{job_id}.spl") print(f"\n[+] Incoming network connection from {addr}") # Read the raw TCP data stream sent by the client network driver with open(raw_path, "wb") as f: while True: data = client.recv(4096) if not data: break f.write(data) print(f"[✔] Received network print data: {raw_path}") client.close() # Convert captured raw stream to PDF convert_to_pdf(raw_path) except KeyboardInterrupt: print("\n[*] Shutting down Network Virtual Printer...") finally: server.close()
if __name__ == "__main__": start_network_printer()
Start your server in the terminal:
python network_virtual_printer.py
Step 2: Install as a TCP/IP Network Printer in Windows
To connect Windows to your Python server, you must add it specifically as a Network Printer using a TCP/IP Port, not as a local port printer.
- Open Control Panel -> Devices and Printers (or press Win + R, type
control printers, and hit Enter). - Click Add a printer.
- Select The printer that I want isn't listed.
- Choose Add a printer using an IP address or hostname, then click Next.
- Set Device type to TCP/IP Device.
- Enter
127.0.0.1in Hostname or IP address. Uncheck "Query the printer and automatically select the driver to use". Click Next. - Wait for detection to finish, then choose Custom -> Settings.
- Ensure Protocol is set to Raw and Port Number is 9100. Click OK, then click Next.
- Choose a driver to format the print job before sending it over the network:
- For PostScript output: Select Generic -> Generic / Text Only or HP Color LaserJet 2800 Series PS.
- For PCL output: Select HP LaserJet 6P or Generic PCL.
- Name the printer (e.g.,
Python TCP Network Printer) and finish installation.
Step 3: Convert Captured Network Streams using VeryPDF
Once the Windows network print driver sends the data over TCP/IP to port 9100, the Python script feeds the captured file directly to VeryPDF SPL to PDF Converter Command Line (spl2pdf.exe).
| Network Driver Type | Raw Stream Format | VeryPDF Processing |
|---|---|---|
| Generic / Text Driver | Raw Text Stream | Converted to Text-based PDF (.pdf) |
| HP PostScript Driver | PostScript (.ps) |
Converted to High-Res Vector PDF (.pdf) |
| HP PCL Driver | PCL5 / PCL6 (.pcl) |
Converted to Searchable PDF (.pdf) |
| Standard Windows Spool | Spool Stream (.spl) |
Converted to Clean PDF (.pdf) |
Step 4: Testing the Network Virtual Printer
- Ensure the Python server script is running.
- Open any document or text editor on your machine.
- Select Print and choose Python TCP Network Printer.
- Observe the terminal output:
[*] Python Network Virtual Printer is active on port 9100...
[+] Incoming network connection from ('127.0.0.1', 58492)
[✔] Received network print data: incoming_raw\network_job_20260820_120000_1.spl
[SUCCESS] Converted to PDF: output_pdf\network_job_20260820_120000_1.pdf
The output PDF will now be ready inside your output_pdf directory.
This is the captured print file,
This is the content of the captured print file, which is a PCL6 file,
Frequently Asked Questions
Is this a local printer driver or a network printer server?
This is a network printer server built with Python sockets. It listens on a network port (9100) and processes print jobs coming over TCP/IP.
Can other computers on my local network send print jobs to this script?
Yes. Change server.bind(("127.0.0.1", 9100)) to server.bind(("0.0.0.0", 9100)). Other machines can then add your computer's IP address as a network TCP/IP printer.
Why does Windows show the printer as "Offline"?
Windows checks network printer status using SNMP. Since Python is only listening on TCP port 9100, open Printer Properties -> Ports -> Configure Port in Windows and uncheck SNMP Status Enabled.
How is a network printer on port 9100 different from a local file virtual printer?
A local virtual printer Hooks directly into the Windows printing subsystem on the same PC. A network printer on port 9100 receives standard socket connections over the network from any OS or system.
Why are my output PDFs blank?
This occurs if the driver sends an unreadable raw format or if VeryPDF does not recognize the stream. Switch your Windows printer driver to a standard PostScript or PCL5 driver.
Can I run multiple network virtual printers simultaneously?
Yes. Bind separate Python script instances to different ports (e.g., 9101, 9102) and set up corresponding TCP/IP network ports in Windows.
Does this setup require VeryPDF?
If you only transmit plain ASCII text, Python can handle the file directly. However, for real page structures, fonts, and graphics sent over PCL/PostScript, a converter tool like VeryPDF is necessary.
How do I make the Python network server run silently in the background?
Run the script using pythonw.exe network_virtual_printer.py or register it as a Windows service using NSSM.
Why does the network printer disconnect during large print jobs?
Ensure your script reads data in a continuous loop (while True: data = client.recv(4096)) until the client closes the socket connection.
How do I delete raw print files automatically after conversion?
Add os.remove(raw_file_path) inside the try block right after the convert_to_pdf() call completes successfully.