No matching definitions.

tur/net

stdlib/net.tur

blocking TCP sockets over a linear Socket handle.

net/tcp-connect, net/tcp-listen and net/accept hand out a Socket; net/send, net/recv and net/shutdown-write use one; net/close releases it. Every call blocks the calling thread -- for the cooperative scheduler use stdlib/async_socket.tur instead. Every fallible call returns (Result T IoError).

Since: Phase LT4

defopaque linear

Socket

(defopaque Socket :int :linear)

a linear (exactly-once) handle to an open socket.

Every Socket must be consumed exactly once with net/close; under -Xlinear dropping one is TUR-E0100 and closing it twice TUR-E0101. The calls that only use a socket (net/send, net/recv, net/accept, ...) borrow it. It is an opaque over the descriptor rather than a one-field struct, so it rides a (Result Socket IoError) as one word.

Since: LT4

defn

socket-fd

(socket-fd [^borrow s :Socket] :Fd)

return the underlying file descriptor from a Socket as an Fd.

sa Socket (borrowed).

The underlying file descriptor wrapped as an Fd.

(socket-fd my-socket)  ; => Fd wrapping 5

Since: LT4

defn

socket-valid?

(socket-valid? [^borrow s :Socket] :bool)

return true if the Socket wraps a non-negative fd.

sa Socket (borrowed).

true if fd >= 0, false otherwise. Every Socket the net/* calls hand out is valid; failure is their (Err e).

(socket-valid? my-socket)  ; => true

Since: LT4

defn

net/tcp-connect

(net/tcp-connect [host :cstr port :int])

open a TCP connection to host:port.

host is a name or a numeric IPv4 / IPv6 address; every address it resolves to is tried in turn until one accepts.

hoste.g. "example.com", "127.0.0.1" or "::1"
portthe TCP port

(Ok s) -- a connected Socket; close it with net/close -- or (Err e): ECONNREFUSED when nothing listens there, EHOSTUNREACH when host does not resolve.

(match (net/tcp-connect "127.0.0.1" 8080)
  (Ok s)  (net/close s)
  (Err e) (Err e))

Since: stdlib-os-surface P3

defn

net/tcp-listen

(net/tcp-listen [host :cstr port :int])

a listening TCP socket on host:port.

hostthe local address to bind: "127.0.0.1" for this machine only,
"0.0.0.0" for every IPv4 interface, "::" for IPv6, or "" for
the first wildcard address the system lists
portthe TCP port; 0 picks a free one (read it with net/local-port)

(Ok s) -- a listening Socket for net/accept; close it with net/close -- or (Err e), e.g. EADDRINUSE. SO_REUSEADDR is set (not on Windows, where it would let another process take the port), so a restarted server can rebind at once.

(match (net/tcp-listen "127.0.0.1" 0)
  (Ok s)  (net/close s)
  (Err e) (Err e))

Since: stdlib-os-surface P3

defn

net/accept

(net/accept [^borrow s :Socket])

wait for the next connection on a listening socket.

sa Socket from net/tcp-listen (borrowed; it keeps listening)

(Ok client) -- the connected Socket; close it with net/close -- or (Err e). A signal caught with signal/handle (stdlib/process.tur) ends the wait with an io-error/interrupted? error, so a server loop can check signal/interrupted? and stop; call again to keep waiting.

(match (net/accept server)
  (Ok c)  (net/close c)
  (Err e) (Err e))

Since: stdlib-os-surface P3

defn

net/send

(net/send [^borrow s :Socket data :cstr])

write a whole string to a connected socket.

Blocks until every byte is handed to the kernel (send(2) may take it in pieces). Writing to a peer that has closed is an EPIPE error, never a SIGPIPE that kills the process.

sa connected Socket (borrowed)
datathe bytes to send, up to the NUL terminator

(Ok n) -- n is the byte count, the length of data -- or (Err e).

(net/send s "GET / HTTP/1.0\r\n\r\n")  ; => (Ok 18)

Since: stdlib-os-surface P3

defn

net/recv

(net/recv [^borrow s :Socket max :int])

read what has arrived on a connected socket, up to max bytes.

Blocks until at least one byte is available or the peer closes. The bytes come back as a cstr, so this suits text protocols: a NUL byte in the data ends the string early.

sa connected Socket (borrowed)
maxthe most bytes to return (> 0)

(Ok (Some text)) -- a fresh heap cstr of 1 to max bytes the caller owns (release with free); (Ok (None)) once the peer has closed its side; (Err e) on a failure, e.g. ECONNRESET -- or io-error/interrupted? when a signal caught with signal/handle ended the wait (nothing was read; call again to keep waiting).

(match (net/recv s 4096)
  (Ok o)  (match o (Some t) (println t) (None) (println "<closed>"))
  (Err e) (println (io-error/message e)))

Since: stdlib-os-surface P3

defn

net/local-port

(net/local-port [^borrow s :Socket])

the local port a socket is bound to.

The way to learn which port net/tcp-listen picked for port 0.

sa bound or connected Socket (borrowed)

(Ok port), or (Err e).

(net/local-port server)  ; => (Ok 49152)

Since: stdlib-os-surface P3

defn

net/shutdown-write

(net/shutdown-write [^borrow s :Socket])

tell the peer no more data is coming (half-close).

The peer's next net/recv answers (Ok (None)) once it has read everything sent before; this side can still receive. The socket stays open -- release it with net/close.

sa connected Socket (borrowed)

(Ok nil), or (Err e).

(net/shutdown-write s)  ; => (Ok nil)

Since: stdlib-os-surface P3

defn

net/close

(net/close [s :Socket])

close a Socket.

sthe Socket (consumed)

(Ok nil), or (Err e). The descriptor is released either way.

(net/close s)  ; => (Ok nil)

Since: stdlib-os-surface P3