Skip to content

Windows Setup

Sockcan provides userspace SocketCAN support on Windows through a daemon-based architecture. This guide covers setting up Sockcan on Windows systems.

Overview

On Windows, Sockcan uses a daemon-based architecture:

  1. A daemon runs locally, connecting to your physical CAN hardware (e.g., PCAN)
  2. Sockcan's userspace implementation provides SocketCAN-compatible sockets
  3. Your application connects to the daemon via the interoperability layer

This allows existing SocketCAN code to work on Windows with minimal changes.


Prerequisites

1. Install a CAN Hardware Driver

Windows doesn't have native SocketCAN support. You'll need:

  • PCAN-USB: Install PEAK-System drivers
  • Other interfaces: Ensure python-can supports your hardware

2. Install python-can

pip install python-can

3. Install Sockcan

pip install sockcan

Usage Modes

Standalone Mode (with Daemon)

Create a local server that bridges your physical CAN hardware:

from sockcan.daemon import SocketcanServer, BusParameters, SocketcanDaemon
from sockcan import build_send_func, build_recv_func

# Create daemon with your PCAN hardware
with SocketcanDaemon() as daemon:
    daemon.register_bus(
        channel="PCAN_USBBUS1",
        interface="pcan",
        bitrate=500000,
    )
    daemon.start()

    # Get a socketcan-like socket from the server
    sock = daemon._servers["PCAN_USBBUS1"].subscribe()

    # Use standard SocketCAN API
    send = build_send_func(sock, expects_msg_cls=False)
    recv = build_recv_func(sock)

    send(0x100, b'\x01\x02\x03\x04', False)
    msg = recv()

The recommended approach for Windows is using the interoperability layer:

from sockcan.daemon import BusParameters
from sockcan.interop import activate_userspace_socketcan, SocketcanDaemonConfig
import can

# Configure for local daemon mode
config = SocketcanDaemonConfig(
    mode="local",
    allow_run_daemon_locally=True,
)

# Activate userspace socketcan with your hardware
activate_userspace_socketcan(
    BusParameters(
        channel="PCAN_USBBUS1",
        interface="pcan",
        bitrate=500000,
    ),
    config=config,
)

# Now use python-can as usual - it automatically uses Sockcan's implementation
bus = can.Bus(interface="socketcan", channel="PCAN_USBBUS1")
msg = bus.recv()
bus.send(can.Message(arbitration_id=0x123, data=[1, 2, 3, 4]))

Daemon Modes

Local Mode (Default)

The daemon runs in a local thread within your application:

from sockcan.interop import activate_userspace_socketcan, SocketcanDaemonConfig
from sockcan.daemon import BusParameters

config = SocketcanDaemonConfig(
    mode="local",
    allow_run_daemon_locally=True,
)

activate_userspace_socketcan(
    BusParameters(channel="PCAN_USBBUS1", interface="pcan"),
    config=config,
)

Pros: - Simple setup - Automatic cleanup on exit - No separate process

Cons: - Daemon runs in your application process - Less suitable for multi-application scenarios

Daemon Mode

Run a separate daemon process accessible via HTTP:

from sockcan.interop import activate_userspace_socketcan, SocketcanDaemonConfig
from sockcan.daemon import BusParameters, ensure_socketcan_daemon_running

config = SocketcanDaemonConfig(
    mode="daemon",
    host="localhost",
    port=8000,
    allow_run_daemon_locally=True,
)

daemon = ensure_socketcan_daemon_running(host="localhost", port=8000)

activate_userspace_socketcan(
    BusParameters(channel="PCAN_USBBUS1", interface="pcan"),
    config=config,
)

Pros: - Separate process (doesn't block application) - Multiple applications can share the same daemon - Remote access possible

Cons: - More complex setup - Requires daemon process management


Using Real CAN Hardware

On Windows, always use the interoperability layer with your hardware:

Example: PCAN-USB

from sockcan.interop import activate_userspace_socketcan, SocketcanDaemonConfig
from sockcan.daemon import BusParameters
import can

activate_userspace_socketcan(
    BusParameters(
        channel="PCAN_USBBUS1",  # Common PCAN channel name
        interface="pcan",
        bitrate=500000,
    ),
)

bus = can.Bus(interface="socketcan", channel="PCAN_USBBUS1")

# Your existing SocketCAN code works unchanged
msg = can.Message(arbitration_id=0x7E8, data=[0x02, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00])
bus.send(msg)

response = bus.recv(timeout=1.0)
print(f"Response: {response}")

Example: Other Interfaces

# Vector CANalyzer
activate_userspace_socketcan(
    BusParameters(channel="CAN1", interface="vector", bitrate=500000),
)

# Kvaser
activate_userspace_socketcan(
    BusParameters(channel="0", interface="kvaser", bitrate=500000),
)

Cross-Platform Development

Sockcan enables writing platform-agnostic CAN code:

import platform
from sockcan.interop import activate_userspace_socketcan, SocketcanDaemonConfig
from sockcan.daemon import BusParameters
import can

def setup_can(channel, interface, bitrate=500000):
    """Platform-aware CAN setup."""
    system = platform.system()

    if system == "Windows":
        # Windows: Use userspace daemon
        config = SocketcanDaemonConfig(mode="local")
        activate_userspace_socketcan(
            BusParameters(channel=channel, interface=interface, bitrate=bitrate),
            config=config,
        )
    else:
        # Linux/macOS: Hijack python-can's socketcan
        from sockcan.interop import hijack_python_can
        hijack_python_can()

    return can.Bus(interface="socketcan", channel=channel)

# Works on both Windows and Linux!
bus = setup_can("PCAN_USBBUS1", "pcan")
bus.send(can.Message(arbitration_id=0x100, data=[1, 2, 3, 4]))

Virtual CAN on Windows

Windows doesn't support virtual CAN interfaces natively. However, you can simulate virtual CAN using the daemon:

from sockcan.interop import activate_userspace_socketcan, SocketcanDaemonConfig
from sockcan.daemon import BusParameters
from sockcan import build_send_func, build_recv_func

# Register a virtual bus (no real hardware)
config = SocketcanDaemonConfig(mode="local")

# First, register with a dummy interface to enable the virtual bus
activate_userspace_socketcan(
    parameters=None,  # No real bus parameters
    config=config,
)

# Create virtual server manually
from sockcan.daemon import SocketcanServer

server = SocketcanServer(use_stream=True)  # Virtual mode
server.start()

sock = server.subscribe()
send = build_send_func(sock, expects_msg_cls=False)
recv = build_recv_func(sock)

# Simulate CAN communication
send(0x123, b'\xaa\xbb\xcc\xdd', False)
msg = recv()

Troubleshooting

No Hardware Detected

RuntimeError: No PCAN devices found

Solution: 1. Verify hardware is connected and powered 2. Install correct drivers 3. Check device appears in Device Manager

Daemon Connection Failed

RuntimeError: Daemon mode is used, but no daemon is running

Solution:

from sockcan.daemon import ensure_socketcan_daemon_running
ensure_socketcan_daemon_running()

Channel Not Found

ValueError: Channel PCAN_USBBUS1 not found

Solution: 1. Verify the channel name matches your hardware 2. List available channels with your CAN driver's tools


Performance Considerations

On Windows, the daemon-based approach may introduce slight latency compared to native Linux SocketCAN. For minimum latency:

  1. Use local mode instead of daemon mode
  2. Reduce network hops (use localhost for daemon mode)
  3. Use SOCK_STREAM mode for streaming applications:
from sockcan.daemon import SocketcanServer

server = SocketcanServer(use_stream=True)  # Lower latency