Every networking page so far dialed a port on an interface. But a great many
connections never leave the machine: a tool talking to its daemon, a health
probe asking a service how it feels, two halves of one deployment sharing a
box. For those, Mica’s net unit has a second kind of address — a name,
under the kernel’s own namespace — and everything else stays exactly as you
learned it. That “everything else stays” is the lesson of this page.
The example is examples/IpcRoad
in the tutorial repository.
Getting the file
make -C examples/IpcRoad runIpcRoad
The name, listened and dialed
the service answered: heard: a line over a name
The name nobody serves
the dial was refused - nothing listens on that nameThe example, walked
A name instead of a port
l := ListenIpc("mica-ipcroad-demo") on fail use l;
...
c := DialIpc("mica-ipcroad-demo") on fail use c;ListenIpc claims a name; DialIpc dials it. The answers are the same
Listener and Connection every other page used, and every verb you know
— Accept parking, the connection traveling into its task by value,
WriteLine and ReadLine speaking UTF-8 on the wire — works unchanged.
When both ends live on one machine, the name beats a port on every count
that matters:
- Nobody picks a number. Ports are a shared 16-bit space you negotiate
with every other program on the box; names are yours to invent. A second
claimant of the same name is refused with
Eaddrinuse— no silent fight, no “address already in use” mystery at 3 a.m. with a port number and no suspect. - No interface is crossed. The bytes never reach a network stack’s outside face, so no firewall has an opinion about them.
- Nothing is left behind. The name lives in the kernel’s abstract namespace and dies with its listener: no socket file lingers in the filesystem for the next run to trip over, and a restart never needs a cleanup ritual.
The honest refusal
ghost := DialIpc("mica-ipcroad-ghost") on fail caught do
begin
case caught of
Econnrefused :
WriteLn(" the dial was refused - nothing listens on that name")
...Dialing a name nobody serves answers Econnrefused — by name, at once,
deterministically. A closed door on the local road is a fact the kernel
states plainly, which is exactly what a start-up ordering check or a health
probe wants: is my daemon up? is one dial and one case arm, no timeout
tuning, no guessing.
Try it
1. Claim the name twice. After the ListenIpc line, add a second
listener asking for the same name and read its refusal:
b := ListenIpc("mica-ipcroad-demo") on fail caught do
begin
case caught of
Eaddrinuse : WriteLn(" second claim refused: Eaddrinuse")
else WriteLn(" second claim failed with code %lld", Ord(caught))
end;
end; second claim refused: Eaddrinuse(Declare b : Listener and import Eaddrinuse : posix.) The name space
polices itself, and the collision has a name the moment it happens — at
claim time, not at some later dial.
2. Watch the name die with its listener. Move the ghost dial to ask for
"mica-ipcroad-demo" — the name that was served — after the
CloseListener line:
the dial was refused - nothing listens on that nameSame refusal as the ghost. The claim ended when the listener closed; nothing lingered. That is the cleanup ritual you do not have to write.
Next
The networking shelf is now walked end to end: the server loop, the chat room’s fan-in, the worker pool’s fan-out, typed values over the wire, the client road, and this page. When your two endpoints are tasks in one program, the same ideas live closer to home — Channel streams is that story. Every example behind the series lives in the tutorial repository.