Net

The Net module provides TCP and UDP networking for Kit. It includes socket operations for both connection-oriented (TCP) and connectionless (UDP) protocols, enabling server and client network communication.

Network Capabilities

Network builtins require authority in scope. Outbound TCP and HTTP calls require TCPConnectAuth, TCPAuth, NetAuth, or RootAuth; listening sockets require TCPListenAuth; UDP helpers require UDPAuth.

TCP Functions

The TCP functions provide connection-oriented socket networking.

Net.tcp-connect
NonEmptyString -> Port -> Result Int NetError
Connect to a TCP server at the given host and port. Returns a socket handle.
match Net.tcp-connect "localhost" 8080
  | Ok socket -> println "Connected!"
  | Err e -> println "Connection failed: ${e}"
Net.tcp-listen
NonEmptyString -> UInt16 -> Result Int NetError
Create a TCP server socket and listen for connections. Returns a listener socket handle.
match Net.tcp-listen "0.0.0.0" 8080
  | Ok listener -> println "Listening on port 8080"
  | Err e -> println "Failed to bind: ${e}"
Net.tcp-accept
PositiveInt -> Result {socket: Int, address: String} NetError
Accept an incoming connection. Blocks until a client connects. Returns the client socket and address.
Net.tcp-send
PositiveInt -> String -> Result Int NetError
Send data over a connection. Returns the number of bytes sent.
Net.tcp-recv
PositiveInt -> PositiveInt -> Result String NetError
Receive up to max_bytes of data from a connection.
Net.tcp-recv-all
PositiveInt -> Result String NetError
Receive all data from a TCP socket until the connection closes.
Net.tcp-close
PositiveInt -> ()
Close a TCP socket.
Net.tcp-shutdown
PositiveInt -> NonEmptyString -> ()
Shutdown a TCP socket. Direction can be "read", "write", or "both".
Net.tcp-local-address
PositiveInt -> Option {host: String, port: Port}
Get the local address of a TCP socket.
Net.tcp-remote-address
PositiveInt -> Option {host: String, port: Port}
Get the remote address of a TCP socket.
Net.tcp-set-timeout
PositiveInt -> NonNegativeInt -> ()
Set the send and receive timeout for a TCP socket in milliseconds.
Net.tcp-set-nodelay
PositiveInt -> Bool -> ()
Enable or disable TCP_NODELAY (Nagle's algorithm). When enabled, data is sent immediately without buffering.

UDP Functions

The UDP functions provide connectionless datagram networking.

Net.udp-bind
NonEmptyString -> UInt16 -> Result Int NetError
Create and bind a UDP socket to the specified host and port. Returns a socket handle.
match Net.udp-bind "0.0.0.0" 9000
  | Ok socket -> println "UDP socket ready"
  | Err e -> println "Failed to bind: ${e}"
Net.udp-send-to
PositiveInt -> NonEmptyString -> String -> Result Int NetError
Send a datagram to the specified address. Address should be in "host:port" format.
Net.udp-recv-from
PositiveInt -> PositiveInt -> Result {data: String, address: String} NetError
Receive a datagram. Returns the data and sender's address.
Net.udp-connect
PositiveInt -> NonEmptyString -> Port -> Result () NetError
Associate a UDP socket with a specific remote address. After connecting, you can use udp-send and udp-recv.
Net.udp-send
PositiveInt -> String -> Result Int NetError
Send data on a connected UDP socket.
Net.udp-recv
PositiveInt -> PositiveInt -> Result String NetError
Receive data on a connected UDP socket.
Net.udp-close
PositiveInt -> ()
Close a UDP socket.
Net.udp-local-address
PositiveInt -> Option {host: String, port: Port}
Get the local address of a UDP socket.
Net.udp-set-broadcast
PositiveInt -> Bool -> ()
Enable or disable broadcast on a UDP socket.
Net.udp-set-timeout
PositiveInt -> NonNegativeInt -> ()
Set the send and receive timeout for a UDP socket in milliseconds.

Examples

TCP Echo Server

listener = match Net.tcp-listen "0.0.0.0" 8080
  | Ok sock -> sock
  | Err e ->
    println "Failed to start server: ${e}"
    exit 1

println "Echo server listening on port 8080"

loop = fn =>
  client = match Net.tcp-accept listener
    | Ok c -> c
    | Err e ->
      println "Accept failed: ${e}"
      exit 1

  match Net.tcp-recv client.socket 1024
    | Ok data ->
      Net.tcp-send client.socket data
      Net.tcp-close client.socket
    | Err _ ->
      Net.tcp-close client.socket

  loop()

loop()

TCP Client

socket = match Net.tcp-connect "localhost" 8080
  | Ok sock -> sock
  | Err e ->
    println "Connection failed: ${e}"
    exit 1

Net.tcp-send socket "Hello, server!"

match Net.tcp-recv socket 1024
  | Ok response ->
    println "Response: ${response}"
  | Err e ->
    println "Receive failed: ${e}"

Net.tcp-close socket

UDP Example

socket = match Net.udp-bind "0.0.0.0" 9000
  | Ok sock -> sock
  | Err e ->
    println "Failed to bind: ${e}"
    exit 1

Net.udp-send-to socket "localhost:9001" "Hello via UDP!"
Net.udp-close socket

Error Types

The Net module exports a NetError type for networking-specific errors.

type NetError =
  | TCPListenError{message: String}
  | TCPConnectionError{message: String}
  | TCPAcceptError{message: String}
  | TCPSendError{message: String}
  | TCPRecvError{message: String}
  | UDPBindError{message: String}
  | UDPConnectionError{message: String}
  | UDPSendError{message: String}
  | UDPRecvError{message: String}
  | SocketError{message: String}

Handling Network Errors

match Net.tcp-connect "localhost" 8080
  | Ok socket -> println "Connected!"
  | Err (TCPConnectionError{message}) ->
      println "Connection error: ${message}"
  | Err (TCPSendError{message}) ->
      println "Send error: ${message}"
  | Err (TCPRecvError{message}) ->
      println "Receive error: ${message}"
  | Err e ->
      println "Error: ${e}"