### lyng.io.net — TCP and UDP sockets for Lyng scripts This module provides minimal raw transport networking for Lyng scripts. It is implemented in `lyngio` and backed by Ktor sockets on the JVM and Linux Native, and by Node networking APIs on JS/Node runtimes. > **Note:** `lyngio` is a separate library module. It must be explicitly added as a dependency to your host application and initialized in your Lyng scopes. > > **Important native platform limit:** current native TCP/UDP support is backed by a selector with a per-process file descriptor ceiling. On Linux/macOS native targets this makes high-connection-count servers and same-process load tests unsuitable once the process approaches that limit. > > **Recommendation:** for serious HTTP/TCP servers, prefer the JVM target today. On native targets, keep concurrency bounded, batch local load tests in waves, and use multiple worker processes behind a reverse proxy if you need more throughput before the backend is reworked. > > **Need this fixed?** Please open or upvote an issue at so native high-concurrency networking can be prioritized. --- #### Install the module into a Lyng session Kotlin (host) bootstrap example: ```kotlin import net.sergeych.lyng.EvalSession import net.sergeych.lyng.Scope import net.sergeych.lyng.io.net.createNetModule import net.sergeych.lyngio.net.security.PermitAllNetAccessPolicy suspend fun bootstrapNet() { val session = EvalSession() val scope: Scope = session.getScope() createNetModule(PermitAllNetAccessPolicy, scope) session.eval("import lyng.io.net") } ``` --- #### Using from Lyng scripts Capability checks and address resolution: import lyng.io.net val a: SocketAddress = Net.resolve("127.0.0.1", 4040)[0] [Net.isSupported(), a.toString(), a.resolved, a.ipVersion == IpVersion.IPV4] >>> [true,127.0.0.1:4040,true,true] TCP client connect, write, read, and close: import lyng.buffer import lyng.io.net val socket = Net.tcpConnect("127.0.0.1", NET_TEST_TCP_PORT) socket.writeUtf8("ping") socket.flush() val reply = (socket.read(16) as Buffer).decodeUtf8() socket.close() reply >>> "reply:ping" Lyng TCP server socket operations with `tcpListen()` and `accept()`: import lyng.buffer import lyng.io.net val server = Net.tcpListen(0, "127.0.0.1") val port = server.localAddress().port val accepted = launch { val client = server.accept() val line = (client.read(4) as Buffer).decodeUtf8() client.writeUtf8("echo:" + line) client.flush() client.close() server.close() line } val socket = Net.tcpConnect("127.0.0.1", port) socket.writeUtf8("ping") socket.flush() val reply = (socket.read(16) as Buffer).decodeUtf8() socket.close() [accepted.await(), reply] >>> [ping,echo:ping] UDP bind, send, receive, and inspect sender address: import lyng.buffer import lyng.io.net val server = Net.udpBind(0, "127.0.0.1") val client = Net.udpBind(0, "127.0.0.1") client.send(Buffer("ping"), "127.0.0.1", server.localAddress().port) val d = server.receive() client.close() server.close() [d.data.decodeUtf8(), d.address.port > 0] >>> [ping,true] --- #### API reference ##### `Net` (static methods) - `isSupported(): Bool` — Whether any raw networking support is available. - `isTcpAvailable(): Bool` — Whether outbound TCP sockets are available. - `isTcpServerAvailable(): Bool` — Whether listening TCP server sockets are available. - `isUdpAvailable(): Bool` — Whether UDP datagram sockets are available. - `resolve(host: String, port: Int): List` — Resolve a host and port into concrete addresses. - `tcpConnect(host: String, port: Int, timeoutMillis: Int? = null, noDelay: Bool = true): TcpSocket` — Open an outbound TCP socket. - `tcpListen(port: Int, host: String? = null, backlog: Int = 128, reuseAddress: Bool = true): TcpServer` — Start a listening TCP server socket. - `udpBind(port: Int = 0, host: String? = null, reuseAddress: Bool = true): UdpSocket` — Bind a UDP socket. ##### `SocketAddress` - `host: String` - `port: Int` - `ipVersion: IpVersion` - `resolved: Bool` - `toString(): String` ##### `TcpSocket` - `isOpen(): Bool` - `localAddress(): SocketAddress` - `remoteAddress(): SocketAddress` - `read(maxBytes: Int = 65536): Buffer?` - `readLine(): String?` - `write(data: Buffer): void` - `writeUtf8(text: String): void` - `flush(): void` - `close(): void` ##### `TcpServer` - `isOpen(): Bool` - `localAddress(): SocketAddress` - `accept(): TcpSocket` - `close(): void` ##### `UdpSocket` - `isOpen(): Bool` - `localAddress(): SocketAddress` - `receive(maxBytes: Int = 65536): Datagram?` - `send(data: Buffer, host: String, port: Int): void` - `close(): void` ##### `Datagram` - `data: Buffer` - `address: SocketAddress` --- #### Security policy The module uses `NetAccessPolicy` to authorize network operations before they are executed. - `NetAccessPolicy` — interface for custom policies - `PermitAllNetAccessPolicy` — allows all network operations - `NetAccessOp.Resolve(host, port)` - `NetAccessOp.TcpConnect(host, port)` - `NetAccessOp.TcpListen(host, port, backlog)` - `NetAccessOp.UdpBind(host, port)` --- #### Platform support - **JVM:** supported - **Android:** supported via the Ktor CIO and Ktor sockets backends - **JS/Node:** supported for `resolve`, TCP client/server, and UDP - **JS/browser:** unsupported; capability checks report unavailable - **Linux Native:** supported via Ktor sockets - **Apple Native:** enabled via the shared native Ktor sockets backend; compile-verified, runtime not yet host-verified - **Other native targets:** currently report unsupported; use capability checks before relying on raw sockets