--- title: "A Small socketR Example" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{A Small socketR Example} %\VignetteEngine{knitr::rmarkdown} \usepackage[utf8]{inputenc} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` This example creates a TCP server and client on the IPv4 loopback interface. The server listens on an automatically assigned port, accepts the client, and echoes one message. ```{r tcp-loopback, eval=FALSE} library(socketR) local({ server <- socket_create("inet", "stream") client <- socket_create("inet", "stream") peer <- NULL on.exit({ if (!is.null(peer) && socket_is_open(peer)) socket_close(peer) if (socket_is_open(client)) socket_close(client) if (socket_is_open(server)) socket_close(server) }, add = TRUE) socket_reuse_address(server, TRUE) socket_bind(server, "127.0.0.1", 0L) port <- socket_local_name(server)$port socket_listen(server) socket_connect(client, "127.0.0.1", port) peer <- socket_accept(server) socket_send(client, "hello from R") socket_poll(peer, "read", timeout_ms = 1000L) message <- rawToChar(socket_receive(peer, n = 12L)) message }) ``` The same handle API also supports IPv6, UDP datagrams, nonblocking mode, readiness polling, shutdown, and generic typed socket options. See the function reference for those lower-level operations and the `Socket` R6 class for method-style usage. ## Automatic IPv4/IPv6 selection The `socket_listen_auto()` and `socket_connect_auto()` helpers resolve and try IPv6 and IPv4 endpoints in preference order. This avoids hard-coding an address family when both may be available. ```{r tcp-auto, eval=FALSE} library(socketR) server <- socket_listen_auto(port = 0L) client <- socket_connect_auto(server$address, server$port) peer <- socket_accept(server) socket_send(client, "hello from auto-connect") socket_poll(peer, "read", timeout_ms = 1000L) rawToChar(socket_receive(peer, n = 23L)) socket_close(peer) socket_close(client) socket_close(server) ``` The default preference is IPv6 followed by IPv4. Use `prefer = "inet"` or `prefer = "inet6"` when an application requires a specific address family. ## Unix-domain sockets Unix-domain sockets communicate between processes on the same host using a filesystem path instead of an IP address and port. ```{r unix-domain, eval=FALSE} library(socketR) path <- tempfile("socketr-") server <- socket_create("unix", "stream") client <- socket_create("unix", "stream") peer <- NULL on.exit({ if (!is.null(peer) && socket_is_open(peer)) socket_close(peer) if (socket_is_open(client)) socket_close(client) if (socket_is_open(server)) socket_close(server) if (file.exists(path)) unlink(path) }, add = TRUE) socket_bind(server, path) socket_listen(server) socket_connect(client, path) peer <- socket_accept(server) socket_send(client, "hello over Unix") socket_poll(peer, "read", timeout_ms = 1000L) rawToChar(socket_receive(peer, n = 15L)) ``` The path must be removed after use before another server binds to the same Unix-domain socket address.