Add printer, then Scan, lists the printers SlicerX can see. It only lists them. Nothing connects until you pick one and enter its code or key.
For users
What a scan does
| Printer | How it is found | What SlicerX sends |
|---|---|---|
| Bambu Lab | It announces itself on the network (SSDP on UDP 2021 and 1990). | Nothing. SlicerX only listens. |
| Klipper with Moonraker | It announces _moonraker._tcp with multicast DNS. |
One multicast DNS question. |
| OctoPrint | It announces _octoprint._tcp. |
One multicast DNS question. |
| PrusaLink | It may announce _prusalink._tcp. This has not been seen on a printer yet. |
One multicast DNS question. |
| Elegoo Centauri Carbon | It answers one broadcast on UDP port 3000. | One broadcast, sent when you start the scan and never in the background. |
| Duet, Creality on stock firmware, Snapmaker | They do not announce themselves. | Nothing. Enter the IP address. |
A scan takes about three seconds. It lists only printers on your own network; anything else is dropped.
If a scan finds nothing
- Check that the computer and the printer are on the same network. A guest Wi-Fi, a VLAN or a router setting called client isolation or AP isolation blocks announcements.
- Check that the printer is on and connected. Bambu Lab printers announce themselves only while awake.
- Multicast DNS uses UDP 5353. A firewall on the computer may block it. Allow SlicerX, or enter the IP address by hand.
- Enter the IP address by hand. Every guide says where to read it on the printer.
The browser build finds printers through sx-link, the small program that runs on your computer, so a scan there sees your network, not the browser's.
For integrators
discover in sx-link
{ "id": 7, "method": "discover", "params": { "timeoutMs": 3000 } }timeoutMs is 300 to 10000 (default 3000). The reply is {"printers": DiscoveredPrinter[]}, sorted by plugin and host:
interface DiscoveredPrinter {
plugin: string // a printer plugin id, such as "moonraker"
host: string // IP address on the local network
port?: number
name?: string // the announced instance or printer name
model?: string
serial?: string // Bambu Lab
}@slicerx/link-client exposes it as client.discover(timeoutMs?). The bridge runs every connector's own discovery and the mDNS browse at once and merges the results: the same plugin and host counts once, and a host that is not on the local network (is_lan_host) is dropped. Nothing runs unless a paired client calls it, so a scan is always the user's action. sx-link --no-mdns turns mDNS browsing and advertising off; the connector discovery still runs.
mDNS in sx_connect::mdns
A small RFC 6762 and RFC 6763 implementation: a packet parser and encoder, browse, browse_printers and Advert. browse sends its query from an ephemeral port, so responders answer to that port by unicast (RFC 6762 section 6.7) and nothing has to bind 5353. The query is repeated after a third and two thirds of the window, because multicast loses packets. The parser follows only backward compression pointers, caps names at 255 bytes and refuses truncated packets.
The service types browsed are in PRINTER_SERVICES. _moonraker._tcp and _octoprint._tcp are announced by those projects. _prusalink._tcp, _prusa-link._tcp and _duet._tcp are the names their documentation suggests and are unverified on hardware. A printer found this way arrives as a moonraker, octoprint, prusalink or duet printer; the user still picks the brand entry when the printer is a Creality or Snapmaker that runs Klipper.
Testing
browse_finds_a_responder_over_udp in src/mdns.rs runs a responder on a local socket. discover_lists_printers_announced_over_mdns_and_drops_addresses_off_the_network in link/tests/link.rs answers a browse with a printer on the mock Moonraker and one on a public address, checks that only the first is listed, then adds it and reads its status from the mock.