net/tcp
TCP servers and clients: listening, connecting, reading and writing, TLS and a connection pool.
import net.tcp
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| Name | Type | Description |
|---|---|---|
fd | i64 = -1 | The socket descriptor; -1 means invalid. |
port | int = 0 | The port the server listens on. |
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))
endConn
struct Conn| Name | Type | Description |
|---|---|---|
fd | i64 = -1 | The socket descriptor; -1 means invalid. |
The example for this item is shown with the ones above: net-tcp-Echo.salam
PoolEntry
struct PoolEntry| Name | Type | Description |
|---|---|---|
key | str = "" | The host and port. |
conn | Conn | The connection. |
put_at_ms | i64 = 0 | When it was returned to the pool. |
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)
endPoolEntries
struct PoolEntries| Name | Type | Description |
|---|---|---|
items | Vector | The connections. |
The example for this item is shown with the ones above: net-tcp-Pool.salam
Pool
struct Pool| Name | Type | Description |
|---|---|---|
entries | PoolEntries | The idle connections. |
idle_ttl_ms | i64 = 30000 | The 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): ServerThe example for this item is shown with the ones above: net-tcp-Echo.salam
Ok
func Ok(srv: Server): boolThe example for this item is shown with the ones above: net-tcp-Echo.salam
Port
func Port(srv: Server): intThe example for this item is shown with the ones above: net-tcp-Echo.salam
Accept
func Accept(srv: Server): ConnThe example for this item is shown with the ones above: net-tcp-Echo.salam
CloseServer
func CloseServer(srv: Server)The example for this item is shown with the ones above: net-tcp-Echo.salam
ConnOk
func ConnOk(c: Conn): boolThe example for this item is shown with the ones above: net-tcp-Echo.salam
Read
func Read(c: Conn, max: int): strmax 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): intThe example for this item is shown with the ones above: net-tcp-Echo.salam
ReadBytes
func ReadBytes(c: Conn, buf: void*, max: int): intmax bytes into memory and returns how many; zero or less means the end or an error.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)
endWriteBytes
func WriteBytes(c: Conn, ptr: void*, n: int): intn bytes from memory.The example for this item is shown with the ones above: net-tcp-Bytes.salam
Close
func Close(c: Conn)The example for this item is shown with the ones above: net-tcp-Echo.salam
Dial
func Dial(host: str, port: int): ConnConnOk 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.Connimport net.tcp
import tls
func main:
_ := tcp.DialTLS("example.com", 443)
plain := tcp.Dial("example.com", 443)
_ := tcp.UpgradeTLS(plain, tls.NewConfig("example.com"))
endUpgradeTLS
func UpgradeTLS(c: Conn, cfg: tls.Config): tls.ConnThe example for this item is shown with the ones above: net-tcp-TLS.salam
ConnFromFd
func ConnFromFd(fd: i64): ConnThe 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)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)The example for this item is shown with the ones above: net-tcp-Bytes.salam
SetWriteDeadline
func SetWriteDeadline(c: Conn, millis: int)The example for this item is shown with the ones above: net-tcp-Bytes.salam
SetDeadline
func SetDeadline(c: Conn, millis: int)The example for this item is shown with the ones above: net-tcp-Echo.salam
SetKeepAlive
func SetKeepAlive(c: Conn, enable: bool)The example for this item is shown with the ones above: net-tcp-Echo.salam
SetNoDelay
func SetNoDelay(c: Conn, enable: bool)The example for this item is shown with the ones above: net-tcp-Echo.salam
NewPool
func NewPool(): PoolThe 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): Connnow_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)The example for this item is shown with the ones above: net-tcp-Pool.salam
PoolLen
func PoolLen(p: Pool): intThe example for this item is shown with the ones above: net-tcp-Pool.salam