net(3)

๐Ÿ“ฆ
version 3.8.0 ยท 3 versions
, in debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

โœจ NAME โœจ

okay so bestie, meet net(3) โ€” it's literally the standard networking module ๐Ÿ’– like the whole toolkit for making your programs talk to other machines across the internet. no cap.


๐ŸŒ STANDARD NETWORKING MODULE ๐ŸŒ

So the Standard Networking module is an original implementation of networking facilities for the Internet Protocol. ๐Ÿ›ฐ๏ธ It's got your standard TCP and UDP sockets for point-to-point communication, and it also has multicast socket. It's also serving up a ton of functions and objects for address manipulation, because of course it is. ๐Ÿ’… And plot twist โ€” it's also designed to support IP version 6 with certain platforms. she's versatile like that. ๐Ÿ‘‘

๐Ÿ“ IP address

So IP-based communication uses a standard address to reference a particular peer. With IP version 4, the standard dot notation is with 4 bytes. With IP version 6, the standard semicolon notation is with 16 bytes. The current implementation supports both versions. slay.

127.0.0.1       # ipv4 localhost
0:0:0:0:0:0:0:1 # ipv6 localhost

IP address architecture and behavior are described in various documents as listed in the bibliography. ๐Ÿ“š

๐ŸŒˆ Domain name system

The translation between a host name and an IP address is performed by a resolver which uses the Domain Name System or DNS. Access to the DNS is automatic with the implementation. Depending on the machine resolver configuration, a particular domain name translation might result in an IP version 4 or IP version 6 address. Most of the time, an IP version 4 address is returned. The mapping between an IP address and a host name returns the associated canonical name for that IP address. This is the reverse of the preceding operation. ๐Ÿ” it's giving full circle.

๐ŸŽ€ The Address class

The Address class allows manipulation of IP address. The constructor takes a string as its arguments. The argument string can be either an IP address or a host name which can be qualified or not. And here's the thing โ€” when the address is constructed with a host name, the IP address resolution is done immediately. no waiting around, she's efficient. ๐Ÿ’…

๐Ÿ” Name to address translation

The most common operation is to translate a host name to its equivalent IP address. Once the Address object is constructed, the get-address method returns a string representation of the internal IP address. The following example prints the IP address of the localhost, that is 127.0.0.1 with IP version 4. iconic behavior honestly.

# load network module
interp:library "afnix-net"
# get the localhost address
const addr (afnix:net:Address "localhost")
# print the ip address
println (addr:get-address)

As another example, the get-host-name function returns the host name of the running machine. The previous example can be used to query its IP address. ๐Ÿซถ

๐Ÿ”„ Address to name translation

The reverse operation of name translation maps an IP address to a canonical name. Heads up though bestie โ€” it shall be noted that the reverse lookup is not done automatically, unless the reverse flag is set in the constructor. The get-canonical-name method of the Address class returns such name. Example XNET001.als is a demonstration program which prints the address original name, the IP address and the canonical name. Feel free to use it with your favorite site to check the equivalence between the original name and the canonical name. ๐Ÿ‘€

# print the ip address information of the arguments
# usage: axi XNET001.als [hosts ...]
# get the network module
interp:library "afnix-net"
# print the ip address
const ip-address-info (host) {
  try {
    const addr (afnix:net:Address host true)
    println "host name        : " (addr:get-name)
    println "  ip address     : " (addr:get-address)
    println "  canonical name : " (
      addr:get-canonical-name)
    # get aliases
    const size (addr:get-alias-size)
    loop (trans i 0) (< i size) (i:++) {
      println "  alias address  : " (
        addr:get-alias-address i)
      println "  alias name     : " (
        addr:get-alias-name i)
    }
  } (errorln "error: " what:reason)
}
# get the hosts
for (s) (interp:argv) (ip-address-info s)
zsh> axi net-0001.als localhost
host name        : localhost
ip address     : 127.0.0.1
canonical name : localhost

๐Ÿงฎ Address operations

The Address class provides several methods and operators that ease the address manipulation in a protocol independent way. For example, the == operator compares two addresses. The ++ operator can also be used to get the next IP address. little shortcuts, we love to see it. โœจ

๐Ÿšš Transport layers

The two transport layer protocols supported by the Internet protocol is the TCP, a full-duplex oriented protocol, and UDP, a datagram protocol. TCP is a reliable protocol while UDP is not. By reliable, we mean that the protocol provides automatically some mechanisms for error recovery, message delivery, acknowledgment of reception, etc... The use of TCP vs. UDP is dictated mostly by the reliability concerns, while UDP reduces the traffic congestion. so basically TCP is the dependable bestie and UDP is the chaotic one. ๐Ÿ’€

๐Ÿ”Œ Service port

In the client-server model, a connection is established between two hosts. The connection is made via the IP address and the port number. For a given service, a port identifies that service at a particular address. This means that multiple services can exist at the same address. More precisely, the transport layer protocol is also used to distinguish a particular service. The network module provides a simple mechanism to retrieve the port number, given its name and protocol. The function get-tcp-service and get-udp-service returns the port number for a given service by name. For example, the daytime server is located at port number 13. ๐Ÿ•

assert 13 (afnix:net:get-tcp-service "daytime")
assert 13 (afnix:net:get-udp-service "daytime")

๐Ÿค Host and peer

With the client server model, the only information needed to identify a particular client or server is the address and the port number. When a client connects to a server, it specifies the port number the server is operating. The client uses a random port number for itself. When a server is created, the port number is used to bind the server to that particular port. And here's the tea โ€” if the port is already in use, that binding will fail. ๐Ÿ˜ญ From a reporting point of view, a connection is therefore identified by the running host address and port, and the peer address and port. For a client, the peer is the server. For a server, the peer is the client. that's the whole dynamic right there.

๐Ÿ“ž TCP client socket

The TcpClient class creates an TCP client object by address and port. The address can be either a string or an Address object. During the object construction, the connection is established with the server. Once the connection is established, the client can use the read and write method to communicate with the server. The TcpClient class is derived from the Socket class which is derived from the InputStream and OutputStream classes. family tree is giving royal lineage. ๐Ÿ‘‘

โ˜€๏ธ Day time client

The simplest example is a client socket which communicates with the daytime server. The server is normally running on all machines and is located at port 13.

# get the network module
interp:library "afnix-net"
# get the daytime server port
const port (afnix:net:get-tcp-service "daytime")
# create a tcp client socket
const s (afnix:net:TcpClient "localhost" port)
# read the data - the server close the connection
while (s:valid-p) (println (s:readln))

Example 3201.als in the example directory prints the day time of the local host without argument or the day time of the argument. Feel free to use it with www.afnix.org. And bestie, real talk โ€” if the server you are trying to contact does not have a day time server, an exception will be raised and the program terminates. so maybe don't do that. ๐Ÿ™ˆ

zsh> axi 3201.als www.afnix.org

๐ŸŒ HTTP request example

Another example which illustrates the use of the TcpClient object is a simple client which downloads a web page. At this stage we are not concerned with the URL but rather the mechanics involved. The request is made by opening a TCP client socket on port 80 (the HTTP server port) and sending a request by writing some HTTP commands. When the commands have been sent, the data sent by the server are read and printed on the standard output. Note that this example is not concerned by error detection. โš ๏ธ she's just here for the vibes.

# fetch an html page by host and page
# usage: axi 3203.als [host] [page]
# get the network module
interp:library "afnix-net"
interp:library "afnix-sys"
# connect to the http server and issue a request
const send-http-request (host page) {
  # create a client sock on port 80
  const s     (afnix:net:TcpClient host 80)
  const saddr (s:get-socket-address)
  # format the request
  s:writeln "GET " page " HTTP/1.1"
  s:writeln "Host: " (saddr:get-canonical-name)
  s:writeln "Connection: close"
  s:writeln "User-Agent: afnix tcp client example"
  s:newline
  # write the result
  while (s:valid-p) (println (s:readln))
}
# get the argument
if (!= (interp:argv:length) 2) (afnix:sys:exit 1)
const host (interp:argv:get 0)
const page (interp:argv:get 1)
# send request
send-http-request host page

๐Ÿ“ก UDP client socket

UDP client socket is similar to TCP client socket. However, due to the unreliable nature of UDP, UDP clients are somehow more difficult to manage. Since there is no flow control, it becomes more difficult to assess whether or not a datagram has reached its destination. The same applies for a server, where a reply datagram might be lost. The UdpClient class is the class which creates a UDP client object. Its usage is similar to the TcpClient. she's the wild child of the family, for real. ๐Ÿฆ‹

โฐ The time client

The UDP time server normally runs on port 37 is the best place to enable it. A UDP client is created with the UdpClient class. Once the object is created, the client sends an empty datagram to the server. The server sends a reply datagram with 4 bytes, in network byte order, corresponding to the date as of January 1st 1900. Example 3204.als prints date information after contacting the local host time server or the host specified as the first argument. โญ

# get the libraries
interp:library "afnix-net"
interp:library "afnix-sys"
# get the daytime server port
const port (afnix:net:get-udp-service "time")
# create a client socket and read the data
const print-time (host) {
  # create a udp client socket
  const s (afnix:net:UdpClient host port)
  # send an empty datagram
  s:write
  # read the 4 bytes data and adjust to epoch
  const buf (s:read 4)
  const val (- (buf:get-quad) 2208988800)
  # format the date
  const time (afnix:sys:Time val)
  println (time:format-date) ' ' (time:format-time)
}
# check for one argument or use localhost
const host (if (== (interp:argv:length) 0)
  "localhost" (interp:argv:get 0))
print-time host

and that's part 1 bestie, but we are so not done โ€” more is coming. ๐Ÿซถ

okay so this example needs a whole lil debrief, bestie, because there's so much going on in it ๐Ÿ’…

first off: the write method with no argument sends an empty datagram. yes, an empty one. that's the whole trick โ€” that datagram is what pokes the server awake. then read grabs 4 bytes off the reply datagram and drops them into a Buffer object. those bytes are chilling in network byte order, so you convert them into an actual integer with the get-quad method. and finally, because the Time class counts its epochs from January 1st 1970, you subtract the constant 2208988800 from your result. why? because the time server is sending you the date referenced to January 1st 1900. rude of it, honestly. you can find out more about the time server in RFC738.


๐Ÿซถ More on reliability ๐Ÿซถ

ngl the previous example has some built-in problems, and it's all because UDP is unreliable. if that first datagram gets lost? the read method just blocks indefinitely. not a vibe. and there's another scenario that makes read block too: the server's reply datagram getting lost. both of these can generally be fixed by checking the socket with a timeout using the valid-p method. give it one argument, the method will timeout and return false. and when that happens, you just send a new datagram to the server. Example 3205.als shows exactly this. here's the extracted code, bestie:

# create a client socket and read the data
const print-time (host) {
  # create a udp client socket
  const s (afnix:net:UdpClient host port)
  # send an empty datagram until the socket is valid
  s:write
  # retransmit datagram each second
  while (not (s:valid-p 1000)) (s:write)
  # read the 4 bytes data and adjust to epoch
  const buf (s:read 4)
  const val (- (buf:get-quad) 2208988800)
  # format the date
  const time (afnix:sys:Time val)
  println (time:format-date) ' ' (time:format-time)
}
heads up: this solution is a naive one. if you've got multiple datagrams flying around, you must use a sequence number, because otherwise you have zero clue about which datagram got lost. simple rule of thumb? use TCP the moment reliability is a concern โ€” but lowkey that choice might not be so easy.

๐Ÿ’€ Error detection ๐Ÿ’€

since UDP isn't reliable, there's no simple way to detect when a datagram has been lost. and it gets worse: if the server isn't even running, it's not easy to detect that the client datagram got lost either. in that situation, the client might just keep sending datagrams forever without ever getting an answer. ๐Ÿ’€

one solution to this problem is, again, to count how many times a datagram has been re-transmitted and eventually give up after a certain amount of time.


๐Ÿ‘‘ Socket class ๐Ÿ‘‘

the Socket class is the base class for both TcpClient and UdpClient. it hands you methods to query the socket port and address, plus the peer port and address. quick note at this point: the UDP socket is a connected socket, so these methods work just fine on it. get-socket-address and get-socket-port return the address and port of the connected socket, respectively. get-peer-address and get-peer-port return the address and port of the connected socket's peer, respectively. Example 3206.als shows these in action:

# create a client socket and read the data
const print-socket-info (host) {
  # create a tcp client socket
  const s (afnix:net:TcpClient host port)
  # print socket address and port
  const saddr (s:get-socket-address)
  const sport (s:get-socket-port)
  println "socket ip address     : " (
    saddr:get-address)
  println "socket canonical name : " (
    saddr:get-canonical-name)
  println "socket port           : " sport
  # print peer address and port
  const paddr (s:get-peer-address)
  const pport (s:get-peer-port)
  println "peer ip address       : " (
    paddr:get-address)
  println "peer canonical name   : " (
    paddr:get-canonical-name)
  println "peer port             : " pport
}

โœจ Socket predicates โœจ

the Socket class comes with the socket-p predicate. and the respective client objects get their own: the tcp-client-p predicate and the udp-client-p predicate. ๐Ÿฆ‹


๐ŸŒธ TCP server socket ๐ŸŒธ

the TcpServer class creates a TCP server object. there are several constructors for it, so let's go through them, periodt:

  • in its simplest form, without a port, a TCP server gets created on the localhost with an ephemeral port number (i.e. port 0 during the call).
  • with a port number, the TCP server is created on the localhost.
  • for a multi-homed host, the address to use to run the server can be specified as the first argument. that address can be either a string or an Address object. in both cases, the port is specified as the second argument.
  • finally, a third argument called the backlog can be specified to set the number of acceptable incoming connections. that's the maximum number of pending connections while processing a connection.

here's every way to create a TCP server, all cute and lined up:

trans s (afnix:net:TcpServer)
trans s (afnix:net:TcpServer 8000)
trans s (afnix:net:TcpServer 8000 5)
trans s (afnix:net:TcpServer "localhost" 8000)
trans s (afnix:net:TcpServer "localhost" 8000 5)
trans s (afnix:net:TcpServer (
    Address "localhost") 8000)
trans s (afnix:net:TcpServer (
    Address "localhost") 8000 5)

๐ŸŒˆ Echo server example ๐ŸŒˆ

a simple echo server can be built and tested with the standard telnet application. the app echoes every single line you type with the telnet client. the server binds on port 8000, because ports 0 to 1024 are privileged ports (iykyk).

# get the network module
interp:library "afnix-net"
# create a tcp server on port 8000
const srv (afnix:net:TcpServer 8000)
# wait for a connection
const s (srv:accept)
# echo the line until the end
while (s:valid-p) (s:writeln (s:readln))

and the telnet session is honestly so simple. the line hello world gets echoed right back by the server. slay:

zsh> telnet localhost 8000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello world
^D

๐Ÿ’œ The accept method ๐Ÿ’œ

the previous example shows off the mechanics of a server. when the server is created, it's ready to accept connections. the accept method blocks until a client connects with the server. and once the connection is established, accept returns a socket object you can use to read and write data. main character energy, fr fr.

๐ŸŽ€ Multiple connections ๐ŸŽ€

one problem with the previous example: the server accepts only one connection. to accept multiple connections, the accept method has to go in a loop, and the server operation goes in a thread. (and just so you know, there are some situations where a new process might be more appropriate than a thread.) Example 3302.als shows this:

# get the network module
interp:library "afnix-net"
# this function echo a line from the client
const echo-server (s) {
  while (s:valid-p) (s:writeln (s:readln))
}
# create a tcp server on port 8000
const srv (afnix:net:TcpServer 8000)
# wait for a connection
while true {
  trans s (srv:accept)
  launch  (echo-server s)
}

๐Ÿงš UDP server socket ๐Ÿงš

the UdpServer class is similar to the TcpServer object, except there are no backlog parameters. in its simplest form, the UDP server is created on the localhost with an ephemeral port (i.e. port 0). with a port number, the server is created on the localhost. and for a multi-homed host, the address used to run the server can be specified as the first argument โ€” again, either a string or an Address object โ€” and in both cases, the port is specified as the second argument.

trans s (afnix:net:UdpServer)
trans s (afnix:net:UdpServer 8000)
trans s (afnix:net:UdpServer "localhost" 8000)
trans s (afnix:net:UdpServer (
    Address "localhost") 8000)

๐Ÿฆ‹ Echo server example ๐Ÿฆ‹

the echo server can be revisited to work with UDP datagrams. the only difference is the use of the accept method. for a UDP server, that method returns a Datagram object, which you can use to read and write data.

# get the network module
interp:library "afnix-net"
# create a udp server on port 8000
const srv (afnix:net:UdpServer 8000)
# wait for a connection
while true {
  trans dg   (srv:accept)
  dg:writeln (dg:readln)
}

โญ Datagram object โญ

with a UDP server, the accept method returns a Datagram object. because UDP is connection-less, the server has absolutely no idea who the datagram is coming from until that datagram has actually been received. when one arrives, the Datagram object is constructed with the peer address being the source address. standard i/o methods work for reading and writing. and when you use a write method, the data gets sent back to the peer in the form of another datagram.

# wait for a datagram
trans dg (s:accept)
# assert datagram type
assert true (datagram-p dg)
# get contents length
println "datagram buffer size : " (dg:get-buffer-length)
# read a line from this datagram
trans line (dg:readln)
# send it back to the sender
s:writeln line

๐Ÿ“ Input data buffer ๐Ÿ“

for a datagram โ€” and generally speaking, for a UDP socket โ€” all input operations are buffered. meaning: when a datagram is received, the accept method drops all that data into an input buffer. so a read operation doesn't necessarily flush the whole buffer; it consumes only the requested characters.

let's do the math, bestie. say one datagram contains the string hello world:

  • a call to readln returns the entire string.
  • a call to read returns only the character 'h'.
  • subsequent calls return the next available characters.
  • a call like read 5 returns a buffer with 5 characters.
  • subsequent calls return the remaining string.

in any case, get-buffer-length returns the number of available characters in the buffer. and a call to valid-p returns true if there are some characters in the buffer, or if a new datagram has arrived.

โš ๏ธ care should be taken with the read method. if there are only 4 characters in the input buffer and you call read for 10 characters, the method will block until a new datagram is received that can fill the remaining 6 characters. you can dodge this whole situation by using the get-buffer-length and valid-p methods. also note that a timeout can be specified with the valid-p method. ๐Ÿ’…

๐Ÿ”ฅ Low level socket methods ๐Ÿ”ฅ

some folks always prefer to do everything by themselves โ€” and most of the time for good reasons. if that's you, you might have to use the low level socket methods. instead of using a client or server class, the implementation lets you create a TcpSocket or UdpSocket. once that's done, bind, connect and the other methods can be used to create the connection you actually want.

๐Ÿ’– A socket client ๐Ÿ’–

a simple TCP socket client is created with the TcpSocket class. then the connect method is called to establish the connection.

# create an address and a tcp socket
const addr (afnix:net:Address "localhost")
const sid  (afnix:net:TcpSocket)
# connect the socket
sid:connect 13 addr

Okay bestie, once the socket is connected, normal read and write operations can be performed. And after the socket is created, it is possible to set some options. A typical one is NO-DELAY which disable the Naggle algorithm. ๐Ÿซถ

# create an address and a tcp socket
const addr (afnix:net:Address "localhost")
const sid  (afnix:net:TcpSocket)
# disable the naggle algorithm
sid:set-option sid:NO-DELAY true
# connect the socket
sid:connect 13 addr

๐ŸŒ NETWORKING REFERENCE ๐ŸŒ

๐Ÿ“ Address

The Address class is the Internet address manipulation class. She's giving translator energy ๐Ÿ’… โ€” you can use her to perform the conversion between a host name and an IP address, and the opposite is also possible. And finally, the class supports both IP version 4 and IP version 6 address formats. Versatile queen. ๐Ÿ‘‘

Predicate

  • address-p

Inheritance

  • Object

Constructors

  • Address (String) โ€” the Address constructor create an IP address object by name. The name argument is a string of a host name or a valid IP address representation. โœจ
  • Address (String Boolean) โ€” the Address constructor create an IP address object by name and force the reverse lookup resolution depending on the boolean flag value. The first argument is a string of a host name or a valid IP address representation. The second argument is a boolean flag that indicates whether or not reverse lookup must occur during the construction.

Operators

  • == -> Boolean (Address) โ€” returns true if the calling object is equal to the address argument.
  • != -> Boolean (Address) โ€” returns true if the calling object is not equal to the address argument.
  • < -> Boolean (Address) โ€” returns true if the calling address is less than the address object.
  • <= -> Boolean (Address) โ€” returns true if the calling address is less equal than the address object.
  • > -> Boolean (Address) โ€” returns true if the calling address is greater than the address object.
  • >= -> Boolean (Address) โ€” the <= operator returns true if the calling address is greater equal than the address object. (yes girl, the manpage really does say <= there, we're keeping it, no notes ๐Ÿ’€)
  • ++ -> Address (Address) โ€” increments the calling address by one position.

Methods

  • resolve -> String Boolean (none) โ€” resolves an host name and eventually performs a reverse lookup. The first argument is a string of a host name or a valid IP address representation. The second argument is a boolean flag that indicates whether or not reverse lookup must occur during the resolution.
  • get-name -> String (none) โ€” returns the original name used during the object construction.
  • get-address -> String (none) โ€” returns a string representation of the IP address. The string representation follows the IP version 4 or IP version 6 preferred formats, depending on the internal representation.
  • get-vector -> Vector (none) โ€” returns a vector representation of the IP address. The vector result follows the IP version 4 or IP version 6 preferred format, depending on the internal representation.
  • get-canonical-name -> String (none) โ€” returns a fully qualified name of the address. The resulting name is obtained by performing a reverse lookup. Note that the name can be different from the original name. ๐Ÿ˜ญ
  • get-alias-size -> Integer (none) โ€” returns the number of aliases for the address. The number of aliases includes as well the primary resolved name which is located at index 0.
  • get-alias-name -> String (Integer) โ€” returns a fully qualified name of the address alias by index. The first argument is the alias index number which must be in the alias index range. The resulting name is obtained by performing a reverse lookup. Note that the name can be different from the original name. Using index 0 is equivalent to call get-canonical-name.
  • get-alias-address -> String (Integer) โ€” returns a string representation of the IP address alias by index. The first argument is the alias index number which must be in the alias index range. The string representation follows the IP version 4 or IP version 6 preferred formats, depending on the internal representation. Using index 0 is equivalent to call get-address.
  • get-alias-vector -> Vector (Integer) โ€” returns a vector representation of the IP address alias by index. The first argument is the alias index number which must be in the alias index range. The vector result follows the IP version 4 or IP version 6 preferred format, depending on the internal representation. Using index 0 is equivalent to call get-vector.

Functions

  • get-loopback -> String (none) โ€” returns the name of the machine loopback. On a UNIX system, that name is localhost. ๐Ÿ 
  • get-tcp-service -> String (Integer) โ€” returns the name of the tcp service given its port number. For example, the tcp service at port 13 is the daytime server.
  • get-udp-service -> String (Integer) โ€” returns the name of the udp service given its port number. For example, the udp service at port 19 is the chargen server.

๐Ÿ”Œ Socket

The Socket class is a base class for the AFNIX network services. The class is automatically constructed by a derived class and provide some common methods for all socket objects. She's the mom friend of the class hierarchy, holding it all together. ๐ŸŽ€

Predicate

  • socket-p

Inheritance

  • InputStreamOutputStream

Constants

  • REUSE-ADDRESS โ€” used by the set-option method to enable socket address reuse. This option changes the rules that validates the address used by bind. It is not recommended to use that option as it decreases TCP reliability. ๐Ÿšจ
  • BROADCAST โ€” used by the set-option method to enable broadcast of packets. This options only works with IP version 4 address. The argument is a boolean flag only.
  • DONT-ROUTE โ€” used by the set-option method to control if a packet is to be sent via the routing table. This option is rarely used with . The argument is a boolean flag only.
  • KEEP-ALIVE โ€” used by the set-option method to check periodically if the connection is still alive. This option is rarely used with . The argument is a boolean flag only.
  • LINGER โ€” used by the set-option method to turn on or off the lingering on close. If the first argument is true, the second argument is the linger time.
  • RCV-SIZE โ€” used by the set-option method to set the receive buffer size.
  • SND-SIZE โ€” used by the set-option method to set the send buffer size.
  • HOP-LIMIT โ€” used by the set-option method to set packet hop limit.
  • MULTICAST-LOOPBACK โ€” used by the set-option method to control whether or not multicast packets are copied to the loopback. The argument is a boolean flag only.
  • MULTICAST-HOP-LIMIT โ€” used by the set-option method to set the hop limit for multicast packets.
  • MAX-SEGMENT-SIZE โ€” used by the set-option method to set the TCP maximum segment size.
  • NO-DELAY โ€” used by the set-option method to enable or disable the Naggle algorithm.

Methods

  • bind -> none (Integer) โ€” binds this socket to the port specified as the argument.
  • bind -> none (Integer Address) โ€” binds this socket to the port specified as the first argument and the address specified as the second argument.
  • connect -> none (Integer Address [Boolean]) โ€” connects this socket to the port specified as the first argument and the address specified as the second argument. A connected socket is useful with udp client that talks only with one fixed server. The optional third argument is a boolean flag that permits to select whether or not the alias addressing scheme should be used. If the flag is false, the default address is used. If the flag is true, an attempt is made to connect to the first successful address that is part of the alias list.
  • open-p -> Boolean (none) โ€” returns true if the socket is open. The method checks that a descriptor is attached to the object. This does not mean that the descriptor is valid in the sense that one can read or write on it. This method is useful to check if a socket has not been closed. ๐Ÿงš
  • shutdown -> Boolean (none|Boolean) โ€” shutdowns or close the connection. Without argument, the connection is closed without consideration for those symbols attached to the object. With one argument, the connection is closed in one direction only. If the mode argument is false, further receive is disallowed. If the mode argument is true, further send is disallowed. The method returns true on success, false otherwise.
  • ipv6-p -> Boolean (none) โ€” returns true if the socket address is an IP version 6 address, false otherwise.
  • get-socket-address -> Address (none) โ€” returns an address object of the socket. The returned object can be later used to query the canonical name and the ip address.
  • get-socket-port -> Integer (none) โ€” bestie this one just hands you the port number of the socket. that's it, that's the whole vibe. ๐Ÿ”ข
  • get-socket-authority -> String (none) โ€” gives you the authority string, which is the socket's address and port as a lil pair. ๐Ÿ’Œ
  • get-peer-address -> Address (none) โ€” returns an Address object for the socket's peer. keep it around, because you can use it later to query the canonical name and the ip address. so useful. ๐Ÿ‘€
  • get-peer-port -> Integer (none) โ€” the port number of the socket's peer, yes ma'am. ๐ŸŽ€
  • get-peer-authority -> String (none) โ€” the authority string of the socket's peer, formatted as an address and port pair. โœจ
  • set-option -> Boolean (constant [Boolean|Integer] [Integer]) โ€” sets a socket option. first arg is the option you wanna set. second arg is a boolean that turns the option on or off. the optional third arg is an integer, and some options literally need it. ๐Ÿ› ๏ธ
  • set-encoding-mode -> none (Item|String) โ€” sets the input and output encoding mode. form one: you pass an item and the stream encoding mode gets set directly. form two: you pass a string, and that might also mess with the stream transcoding mode. two flavors, one method. ๐Ÿ“
  • set-input-encoding-mode -> none (Item|String) โ€” same deal but for the input only. item = stream encoding mode set directly; string = set by string and might also alter the stream transcoding mode. ๐Ÿ’…
  • get-input-encoding-mode -> Item (none) โ€” returns the input encoding mode. no cap. ๐ŸŒธ
  • set-output-encoding-mode -> none (Item|String) โ€” and this one's the output twin: item sets the stream encoding mode directly, string sets it and might also alter the stream transcoding mode. ๐Ÿฆ‹
  • get-output-encoding-mode -> Item (none) โ€” returns the output encoding mode. and that's the full set. ๐Ÿ˜Œ

๐ŸŒˆ TcpSocket ๐ŸŒˆ

okay so TcpSocket is the base class for all tcp socket objects. it's derived from the Socket class and it brings some specific tcp methods to the table. and here's the tea, bestie: if you create a TcpSocket, you are the one responsible for connecting it to the proper address and port. nobody's gonna do it for you. main character energy means owning your own connections. ๐Ÿ‘‘

Predicate

tcp-socket-p

Inheritance

Socket

Constructors

  • TcpSocket (none) โ€” the TcpSocket constructor creates a brand new tcp socket. โœจ

Methods

  • accept -> TcpSocket (none) โ€” waits for an incoming connection and returns a TcpSocket object all initialized with the connected peer. you can use the resulting socket to do i/o operations. this is the one tcp servers use. ๐Ÿซถ
  • listen -> Boolean (none|Integer) โ€” initializes a socket to accept incoming connections. no argument? the default number of incoming connections is 5. give it an integer and you're specifying how many incoming connections the socket is willing to queue. also used by tcp servers. ๐Ÿ’–

๐ŸŒŸ TcpClient ๐ŸŒŸ

the TcpClient class creates a tcp client by host and port. the host argument can be either a name or an address object, and the port argument is the server port you're contacting. TcpClient is derived from the TcpSocket class. and ngl? this class has no specific methods. it's just here, looking cute. ๐Ÿ’…

Predicate

tcp-client-p

Inheritance

TcpSocket

Constructors

  • TcpClient (String Integer) โ€” creates a new tcp client socket from a host name and a port number. first arg = host name, second arg = port number. simple as that. ๐ŸŽ€

๐Ÿ‘‘ TcpServer ๐Ÿ‘‘

the TcpServer class creates a tcp server by port. there's an optional host argument which can be either a name or an address object, and the port argument is the server port to bind. TcpServer is derived from TcpSocket, and it has no specific methods.

with just one argument, the server binds the port argument on the local host. the backlog can be specified as the last argument. you can also pass the host name as the first argument, the port as the second, and eventually the backlog. note that the host can be either a string or an address object โ€” your call bestie. ๐Ÿฆ‹

Predicate

tcp-server-p

Inheritance

TcpSocket

Constructors

  • TcpServer (none) โ€” creates a default tcp server. the blank canvas era. โœจ
  • TcpServer (Integer) โ€” creates a default tcp server that's bound on the specified port argument. ๐Ÿ”Œ
  • TcpServer (Integer Integer) โ€” creates a default tcp server bound on the specified port argument. the second argument is the backlog value. ๐Ÿ“š
  • TcpServer (String Integer) โ€” creates a tcp server by host name and port number. first argument is the host name, second is the port number. ๐Ÿ’Œ
  • TcpServer (String Integer Integer) โ€” creates a tcp server by host name and port number. first arg = host name, second = port number, and the third argument is the backlog. triple threat. ๐ŸŒˆ

๐Ÿซง Datagram ๐Ÿซง

the Datagram class is a socket class used by udp sockets. a datagram gets constructed by the UdpSocket accept method. its whole purpose? storing the peer information so you can actually reply to whoever sent you something. the datagram also stores the data sent by the peer in a buffer. and listen โ€” this class does not have any constructor, nor any specific method. it just is. ๐Ÿ“

Predicate

datagram-p

Inheritance

Socket

๐Ÿ’œ UdpSocket ๐Ÿ’œ

UdpSocket is the base class for all udp socket objects. it's derived from the Socket class and provides some specific udp methods. ๐ŸŒธ

Predicate

udp-socket-p

Inheritance

Socket

Constructors

  • UdpSocket (none) โ€” creates a new udp socket. fresh out the box. โœจ

Methods

  • accept -> Datagram (none) โ€” waits for an incoming datagram and returns a Datagram object. that datagram comes pre-loaded with the peer address and port, plus the incoming data. it's giving full package. ๐Ÿ“ฆ

๐Ÿงš UdpClient ๐Ÿงš

the UdpClient class creates a udp client by host and port. the host argument can be either a name or an address object, and the port argument is the server port to contact. UdpClient is derived from the UdpSocket class, and it has no specific methods. slay. ๐Ÿ’…

Predicate

udp-client-p

Inheritance

UdpSocket

Constructors

  • UdpClient (String Integer) โ€” creates a new udp client by host and port. first argument is the host name, second argument is the port number. ๐ŸŽ€

โญ UdpServer โญ

the UdpServer class creates a udp server by port. optional host argument can be either a name or an address object, and the port argument is the server port to bind. UdpServer is derived from the UdpSocket class, and โ€” you guessed it โ€” it has no specific methods.

with one argument, the server binds the port argument on the local host. you can also specify the host name as the first argument and the port as the second. note that the host can be either a string or an address object. ๐Ÿ’–

Predicate

udp-server-p

Inheritance

UdpSocket

Constructors

  • UdpServer (none) โ€” creates a default udp server object. defaults are a vibe. ๐ŸŒˆ
  • UdpServer (String|Address) โ€” creates a udp server object by host. the first argument is the host name or the host address. ๐Ÿซถ
  • UdpServer (String|Address Integer) โ€” creates a udp server object by host and port. first argument is the host name or host address, second argument is the port number. โœจ

๐Ÿฆ‹ Multicast ๐Ÿฆ‹

the Multicast class creates a udp multicast socket by port. optional host argument can be either a name or an address object, and the port argument is the server port to bind. Multicast is derived from the UdpSocket class, and it has no specific methods.

with one argument, the server binds the port argument on the local host. you can also give the host name first and the port second. note that the host can be either a string or an address object.

and here's the iconic part: this class is similar to the UdpServer class, except that the socket joins the multicast group at construction and leaves it at destruction. in at birth, out at death. truly a full-circle moment. ๐Ÿ˜ญ๐Ÿ”ฅ

Predicate

multicast-p

Inheritance

UdpSocket

Constructors

  • Multicast (String|Address) โ€” creates a multicast socket object by host. the first argument is the host name or host address. ๐Ÿ’œ
  • Multicast (String|Address Integer) โ€” creates a multicast socket object by host and port. first argument is the host name or host address, second argument is the port number. ๐ŸŒธ

and that's the whole page, bestie!! every last method, every last constructor, nothing skipped, nothing invented. ๐Ÿซถ

this gorgeous little number came to you from the AFNIX Module source at version AFNIX, and it's page net(3) in your manual. go build something cute with sockets, drink some water, and remember: you are the main character of your own network stack. periodt ๐Ÿ’…โœจ๐ŸŽ€

๐Ÿ“ฆ where this page comes from