Networking

Packet options: raw/0, 1/2/4 (length-prefixed framing), line, http, http_bin.

34.1 TCP server with gen_tcp

-module(echo_server).
-export([start/1]).

start(Port) ->
    {ok, Listen} = gen_tcp:listen(Port, [binary, {packet, line}, {active, false}, {reuseaddr, true}]),
    io:format("Listening on ~p~n", [Port]),
    accept(Listen).

accept(Listen) ->
    {ok, Socket} = gen_tcp:accept(Listen),
    Pid = spawn(fun() -> loop(Socket) end),
    ok = gen_tcp:controlling_process(Socket, Pid),
    accept(Listen).

loop(Socket) ->
    case gen_tcp:recv(Socket, 0) of
        {ok, Data} -> gen_tcp:send(Socket, Data), loop(Socket);
        {error, closed} -> ok
    end.

34.2 TCP client

{ok, S} = gen_tcp:connect("localhost", 8080, [binary, {active, false}]),
ok = gen_tcp:send(S, <<"hello\n">>),
{ok, Reply} = gen_tcp:recv(S, 0, 5000),
gen_tcp:close(S).

34.3 Active vs passive sockets

{active, false} passive: call recv/2 — natural back-pressure {active, true} data arrives as {tcp, Socket, Data} messages — no flow control {active, once} / {active, N} one/N messages then passive — best of both

Packet options: raw/0, 1/2/4 (length-prefixed framing), line, http, http_bin.

34.4 UDP

{ok, S} = gen_udp:open(9000, [binary, {active, true}]),
gen_udp:send(S, {127, 0, 0, 1}, 9001, <<"ping">>),
receive {udp, S, IP, Port, Data} -> {IP, Port, Data} end.

34.5 The socket module (OTP 22+)

Low-level, BSD-socket-like NIF API; also usable as a backend for gen_tcp ({inet_backend, socket}).

{ok, S} = socket:open(inet, stream, tcp),
ok = socket:connect(S, #{family => inet, addr => loopback, port => 8080}),
socket:send(S, <<"hi">>).

34.6 SSL/TLS

ssl:start(),
{ok, S} = ssl:connect("example.com", 443, [{verify, verify_peer},
                                          {cacerts, public_key:cacerts_get()},
                                          {server_name_indication, "example.com"}]),
ssl:send(S, <<"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n">>),
{ok, Listen} = ssl:listen(8443, [{certfile, "cert.pem"}, {keyfile, "key.pem"}]).

34.7 Production socket acceptor pools

Ranch (used by Cowboy, RabbitMQ) — handles acceptor pools, connection limits, and protocols.