Make One Echo Server Work with Both TCP and Unix Sockets
In the Write a TCP Echo Server From Scratch challenge,
you built a server that accepts a connection, reads whatever bytes the client
sends, and writes those exact same bytes back. That server listened on a TCP socket -
an AF_INET address like 127.0.0.1:4000.
But SOCK_STREAM is not exclusive to TCP. The very same
listen()/accept()/recv()/send() workflow
also works with a Unix domain socket (AF_UNIX) in the stream mode (SOCK_STREAM) -
a local socket addressed by a filesystem path and reachable only from the same host.

Berkeley Sockets API Cheat Sheet.
In this challenge, you'll make one echo server speak over both kinds of connection-oriented stream sockets, chosen at startup by a single command-line argument.
Your task is to write an echo server that takes the listen address as its only command-line argument and:
- If the argument looks like
unix:///path/to/file, the server creates a Unix domain stream socket and listens on that path. - If the argument looks like
<host>:<port>, the server creates an IPv4 TCP socket and listens on that host and port. - Echoes back every byte it receives from a client, exactly as in the original challenge.
To pass the verification, launch your server twice - two instances of the very same program:
./server 127.0.0.1:4000
./server unix:///tmp/echo.sock
The checker connects to both endpoints and verifies that each one echoes correctly.
You're free to use any language to implement the server. The playground already has gcc (for C/C++), Python, and Go installed. Prefer a different stack? You will need to install it yourself.
Hint 1: One program, two address families
The accept loop, the read-until-EOF logic, and the echo-back logic are identical for both stream sockets. The main difference is how you create and bind the listening socket:
- For
<host>:<port>, create an(AF_INET, SOCK_STREAM)socket and bind it to that host and port - exactly what you did in the original echo server challenge. - For
unix:///path, create an(AF_UNIX, SOCK_STREAM)socket and bind it to the filesystem path (the part afterunix://).
Parse the single argument first, decide which kind of listening socket to make, and then fall through into the same connection-handling loop.
Hint 2: Unbinding a stale Unix socket
A pathname-based Unix domain socket leaves a socket file behind at its bind path.
If that file already exists when you bind(), the call fails with EADDRINUSE
("Address already in use"). Remove a leftover socket file (e.g. with
unlink()/os.unlink/os.Remove) before binding.
Many languages' higher-level helpers won't do this for you, so it's a common first issue.
If you're reusing the address-creation steps from the
How Servers Work: A Hands-On Introduction to TCP Sockets tutorial,
note that everything after bind() can stay the same.