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:
- A daemon runs locally, connecting to your physical CAN hardware (e.g., PCAN)
- Sockcan's userspace implementation provides SocketCAN-compatible sockets
- 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
3. 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()
python-can Drop-in Replacement (Recommended)
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
Solution: 1. Verify hardware is connected and powered 2. Install correct drivers 3. Check device appears in Device Manager
Daemon Connection Failed
Solution:
Channel 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:
- Use local mode instead of daemon mode
- Reduce network hops (use
localhostfor daemon mode) - Use SOCK_STREAM mode for streaming applications: