Standard library · Network

net/tcp

TCP servers and clients: listening, connecting, reading and writing, TLS and a connection pool.

import net.tcp
On this page
  1. Types
  2. Functions

TCP is the base of most internet protocols: a reliable, ordered stream of bytes between two programs. A server listens on a port with Bind and takes each new client with Accept; a client connects with Dial.

Accept and Read wait until data arrives; to serve several clients, handle each in its own thread (spawn) or set a deadline. The examples run on 127.0.0.1.

Types

Server

struct Server
A TCP server listening on one port.
NameTypeDescription
fdi64 = -1The socket descriptor; -1 means invalid.
portint = 0The port the server listens on.
net-tcp-Echo.salam
import net.tcp

mut server := tcp.Server {}

func responder():
    conn := tcp.Accept(server)
    message := tcp.Read(conn, 1024)
    _ := tcp.Write(conn, "echo: " + message)
    tcp.Close(conn)
end

func main:
    server = tcp.Bind(0)
    println tcp.Ok(server), tcp.Port(server) > 0
    t := spawn(responder)
    conn := tcp.Dial("127.0.0.1", tcp.Port(server))
    println tcp.ConnOk(conn)
    tcp.SetDeadline(conn, 2000)
    tcp.SetKeepAlive(conn, true)
    tcp.SetNoDelay(conn, true)
    println tcp.Write(conn, "hello")
    println tcp.Read(conn, 1024)
    tcp.Close(conn)
    join(t)
    tcp.CloseServer(server)
    println tcp.ConnOk(tcp.Dial("127.0.0.1", 1))
end
Outputtrue true true 5 echo: hello false

Conn

struct Conn
One TCP connection.
NameTypeDescription
fdi64 = -1The socket descriptor; -1 means invalid.

The example for this item is shown with the ones above: net-tcp-Echo.salam

PoolEntry

struct PoolEntry
One idle connection in the pool.
NameTypeDescription
keystr = ""The host and port.
connConnThe connection.
put_at_msi64 = 0When it was returned to the pool.
net-tcp-Pool.salam
import net.tcp

func main:
    s := tcp.Bind(0)
    port := tcp.Port(s)
    mut pool := tcp.NewPool()
    conn := tcp.Get(pool, "127.0.0.1", port, 1000)
    println tcp.ConnOk(conn), tcp.PoolLen(pool)
    tcp.Put(pool, "127.0.0.1", port, conn, 1000)
    println tcp.PoolLen(pool)
    again := tcp.Get(pool, "127.0.0.1", port, 2000)
    println again.fd == conn.fd, tcp.PoolLen(pool)
    tcp.Put(pool, "127.0.0.1", port, again, 2000)
    fresh := tcp.Get(pool, "127.0.0.1", port, 2000 + pool.idle_ttl_ms + 1)
    println tcp.ConnOk(fresh), tcp.PoolLen(pool)
    tcp.Close(fresh)
    tcp.CloseServer(s)
end
Outputtrue 0 1 true 0 true 0

PoolEntries

struct PoolEntries
A list of idle connections.
NameTypeDescription
itemsVectorThe connections.

The example for this item is shown with the ones above: net-tcp-Pool.salam

Pool

struct Pool
A pool of idle connections to reuse.
NameTypeDescription
entriesPoolEntriesThe idle connections.
idle_ttl_msi64 = 30000The longest an idle connection is kept; 30 seconds by default.

The example for this item is shown with the ones above: net-tcp-Pool.salam

Functions

Bind

func Bind(port: int): Server
Listens on the given port; port zero means let the system pick a free one.

The example for this item is shown with the ones above: net-tcp-Echo.salam

Ok

func Ok(srv: Server): bool
True when the server was created properly.

The example for this item is shown with the ones above: net-tcp-Echo.salam

Port

func Port(srv: Server): int
The actual port of the server; for when you passed zero.

The example for this item is shown with the ones above: net-tcp-Echo.salam

Accept

func Accept(srv: Server): Conn
Waits for a client to connect and returns its connection.

The example for this item is shown with the ones above: net-tcp-Echo.salam

CloseServer

func CloseServer(srv: Server)
Closes the server.

The example for this item is shown with the ones above: net-tcp-Echo.salam

ConnOk

func ConnOk(c: Conn): bool
True when the connection is up.

The example for this item is shown with the ones above: net-tcp-Echo.salam

Read

func Read(c: Conn, max: int): str
Reads at most max bytes; an empty string when the other side has closed the connection.

The example for this item is shown with the ones above: net-tcp-Echo.salam

Write

func Write(c: Conn, data: str): int
Sends the text and returns the number of bytes sent.

The example for this item is shown with the ones above: net-tcp-Echo.salam

ReadBytes

func ReadBytes(c: Conn, buf: void*, max: int): int
Reads at most max bytes into memory and returns how many; zero or less means the end or an error.
net-tcp-Bytes.salam
import net.tcp
import mem

mut server := tcp.Server {}

func responder():
    conn := tcp.Accept(server)
    tcp.SetReadDeadline(conn, 2000)
    tcp.SetWriteDeadline(conn, 2000)
    _ := tcp.Read(conn, 1024)
    tcp.WriteHTTP(conn, "200 OK", "text/plain", "hello")
    tcp.Close(conn)
end

func main:
    server = tcp.Bind(0)
    t := spawn(responder)
    conn := tcp.Dial("127.0.0.1", tcp.Port(server))
    request := "GET / HTTP/1.0\r\n\r\n"
    println tcp.WriteBytes(conn, request as void*, request.len())
    b := mem.AllocateZeroed(256 as u64)
    mut total := 0
    until true:
        r := tcp.ReadBytes(conn, b, 255)
        if r <= 0:
            break
        end
        total += r
    end
    println total > 0
    again := tcp.ConnFromFd(conn.fd)
    println again.fd == conn.fd
    tcp.Close(conn)
    join(t)
    tcp.CloseServer(server)
    mem.Free(b)
end
Output18 true true

WriteBytes

func WriteBytes(c: Conn, ptr: void*, n: int): int
Sends n bytes from memory.

The example for this item is shown with the ones above: net-tcp-Bytes.salam

Close

func Close(c: Conn)
Closes the connection.

The example for this item is shown with the ones above: net-tcp-Echo.salam

Dial

func Dial(host: str, port: int): Conn
Connects to a host and port; when it fails, ConnOk is false.

The example for this item is shown with the ones above: net-tcp-Echo.salam

DialTLS

func DialTLS(host: str, port: int): tls.Conn
Makes an encrypted TLS connection; for HTTPS and the like.
net-tcp-TLS.salam
import net.tcp
import tls

func main:
    _ := tcp.DialTLS("example.com", 443)
    plain := tcp.Dial("example.com", 443)
    _ := tcp.UpgradeTLS(plain, tls.NewConfig("example.com"))
end

UpgradeTLS

func UpgradeTLS(c: Conn, cfg: tls.Config): tls.Conn
Upgrades an existing plain connection to TLS with the given configuration; as STARTTLS does.

The example for this item is shown with the ones above: net-tcp-TLS.salam

ConnFromFd

func ConnFromFd(fd: i64): Conn
Builds a connection from a socket descriptor that was made somewhere else.

The example for this item is shown with the ones above: net-tcp-Bytes.salam

WriteHTTP

func WriteHTTP(c: Conn, status_line: str, content_type: str, body: str)
Sends a complete HTTP/1.1 response with the status line, the content type, Content-Length and Connection: close; for very simple servers.

The example for this item is shown with the ones above: net-tcp-Bytes.salam

SetReadDeadline

func SetReadDeadline(c: Conn, millis: int)
How many milliseconds a read may wait at most.

The example for this item is shown with the ones above: net-tcp-Bytes.salam

SetWriteDeadline

func SetWriteDeadline(c: Conn, millis: int)
How many milliseconds a write may wait at most.

The example for this item is shown with the ones above: net-tcp-Bytes.salam

SetDeadline

func SetDeadline(c: Conn, millis: int)
Sets the read and write deadlines together.

The example for this item is shown with the ones above: net-tcp-Echo.salam

SetKeepAlive

func SetKeepAlive(c: Conn, enable: bool)
Turns TCP keepalive packets on or off, so a dropped idle connection is noticed.

The example for this item is shown with the ones above: net-tcp-Echo.salam

SetNoDelay

func SetNoDelay(c: Conn, enable: bool)
Turns off Nagle's algorithm so small packets are sent at once; for interactive programs.

The example for this item is shown with the ones above: net-tcp-Echo.salam

NewPool

func NewPool(): Pool
An empty pool.

The example for this item is shown with the ones above: net-tcp-Pool.salam

Get

func Get(p &: Pool, host: str, port: int, now_ms: i64): Conn
When the pool holds a fresh idle connection to this host it returns that one, otherwise it makes a new one. now_ms is the current time.

The example for this item is shown with the ones above: net-tcp-Pool.salam

Put

func Put(p &: Pool, host: str, port: int, c: Conn, now_ms: i64)
Returns a connection to the pool after use.

The example for this item is shown with the ones above: net-tcp-Pool.salam

PoolLen

func PoolLen(p: Pool): int
The number of idle connections in the pool.

The example for this item is shown with the ones above: net-tcp-Pool.salam