
Low-level socket utilities offering full upstream API parity, zero-overhead libc bindings, advanced OS socket options (timeouts, non-blocking, TCP/UDP, multicast), Unix domain sockets, and vectored I/O.
A pure Kotlin Multiplatform transliteration of Rust's battle-tested socket2 crate. socket2-kotlin provides low-level socket utilities and direct OS socket configuration options across all Kotlin Multiplatform targets without unsafe application code.
socket2 (131/131 Socket operations, full Domain, SocketType, SocketProtocol, SockAddr, SockRef, MsgHdr, and TcpKeepalive support).Domain.IPV4, SocketType.STREAM, SocketProtocol.TCP) powered by direct zero-copy bindings to libc-kotlin:0.1.3.wasi:sockets), and JavaScript (Node.js & Browser).embedSwiftExportForXcode), allowing seamless, native Swift imports.SO_REUSEADDR, SO_KEEPALIVE, TCP_NODELAY, SO_LINGER, buffer sizes, timeouts, multicasting (SSM, v4, v6), CPU affinity, and non-blocking cloexec flags.readVectored, writeVectored, sendmsg, recvmsg).| Platform Family | Targets | Status |
|---|---|---|
| Apple Darwin |
macosArm64, iosArm64, iosSimulatorArm64, tvosArm64, tvosSimulatorArm64, watchosDeviceArm64, watchosSimulatorArm64
|
Native POSIX / Swift Export |
| Linux |
linuxX64, linuxArm64
|
Native POSIX |
| Windows | mingwX64 |
Native MinGW / POSIX |
| Android Native |
androidNativeArm64, androidNativeX64
|
Native NDK / Bionic |
| JVM & Android |
jvm (Java 21+ toolchain), android (API 24+, compileSdk 34) |
Java NIO & SocketChannel |
| Web & WASM |
wasmWasi (WASI Preview 2 wasi:sockets), wasmJs, js (Node.js & Browser) |
WebAssembly / JS Sockets |
Add socket2-kotlin to your project's build.gradle.kts:
dependencies {
implementation("io.github.kotlinmania:socket2-kotlin:0.2.0")
}Or in a multiplatform project:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.kotlinmania:socket2-kotlin:0.2.0")
}
}
}import io.github.kotlinmania.socket2.Domain
import io.github.kotlinmania.socket2.SocketProtocol
import io.github.kotlinmania.socket2.SockAddr
import io.github.kotlinmania.socket2.Socket
import io.github.kotlinmania.socket2.SocketAddr
import io.github.kotlinmania.socket2.SocketType
import kotlin.time.Duration.Companion.seconds
// Create an IPv4 non-blocking TCP socket
val server = Socket.new(Domain.IPV4, SocketType.STREAM.nonblocking(), SocketProtocol.TCP)
// Fine-grained socket options
server.setReuseAddress(true)
server.setTcpNodelay(true)
server.setKeepalive(true)
server.setSendBufferSize(65536)
server.setRecvBufferSize(65536)
// Bind to local loopback port 8080
val bindAddr = SockAddr.from(SocketAddr.V4("127.0.0.1", 8080))
server.bind(bindAddr)
// Listen with a connection backlog of 128
server.listen(128)
// Accept client connection
val (clientSocket, clientAddr) = server.accept()
println("Client connected from: ${clientAddr.asSocketIpv4()}")val client = Socket.new(Domain.IPV4, SocketType.STREAM, SocketProtocol.TCP)
val destination = SockAddr.from(SocketAddr.V4("93.184.216.34", 80))
// Connect with a 5-second timeout
client.connectTimeout(destination, 5.seconds)
val request = "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n".encodeToByteArray()
client.send(request)val udpSocket = Socket.new(Domain.IPV4, SocketType.DGRAM, SocketProtocol.UDP)
val peerAddr = SockAddr.from(SocketAddr.V4("127.0.0.1", 9000))
val payload = "Hello from KotlinMania!".encodeToByteArray()
udpSocket.sendTo(payload, peerAddr)
val buffer = ByteArray(1024)
val (bytesReceived, sender) = udpSocket.recvFrom(buffer)
println("Received $bytesReceived bytes from $sender")val unixSocket = Socket.new(Domain.UNIX, SocketType.STREAM, null)
val socketPath = SockAddr.unix("/tmp/kotlinmania-ipc.sock")
unixSocket.bind(socketPath)
unixSocket.listen(32)val header = "HTTP/1.1 200 OK\r\nContent-SocketType: text/plain\r\n\r\n".encodeToByteArray()
val body = "Hello, World!".encodeToByteArray()
// Write multiple buffers in a single syscall
val totalWritten = clientSocket.writeVectored(listOf(header, body))socket2-kotlin exports directly into native Swift modules via Kotlin Multiplatform's Swift Export:
import Socket2
let domain = Domain.IPV4
let socketType = SocketType.STREAM
let protocolType = SocketProtocol.TCP
// Directly interact with Socket2 types in Swift# Run unit and integration tests across all targets (includes host tests, WASI node test, and Swift harness)
./gradlew test
# Full multiplatform compilation verification across all 263 target tasks
./gradlew build
# Run static analysis and formatting audits
./gradlew detekt
./gradlew ktlintCheckrust-lang/socket2 authors.A pure Kotlin Multiplatform transliteration of Rust's battle-tested socket2 crate. socket2-kotlin provides low-level socket utilities and direct OS socket configuration options across all Kotlin Multiplatform targets without unsafe application code.
socket2 (131/131 Socket operations, full Domain, SocketType, SocketProtocol, SockAddr, SockRef, MsgHdr, and TcpKeepalive support).Domain.IPV4, SocketType.STREAM, SocketProtocol.TCP) powered by direct zero-copy bindings to libc-kotlin:0.1.3.wasi:sockets), and JavaScript (Node.js & Browser).embedSwiftExportForXcode), allowing seamless, native Swift imports.SO_REUSEADDR, SO_KEEPALIVE, TCP_NODELAY, SO_LINGER, buffer sizes, timeouts, multicasting (SSM, v4, v6), CPU affinity, and non-blocking cloexec flags.readVectored, writeVectored, sendmsg, recvmsg).| Platform Family | Targets | Status |
|---|---|---|
| Apple Darwin |
macosArm64, iosArm64, iosSimulatorArm64, tvosArm64, tvosSimulatorArm64, watchosDeviceArm64, watchosSimulatorArm64
|
Native POSIX / Swift Export |
| Linux |
linuxX64, linuxArm64
|
Native POSIX |
| Windows | mingwX64 |
Native MinGW / POSIX |
| Android Native |
androidNativeArm64, androidNativeX64
|
Native NDK / Bionic |
| JVM & Android |
jvm (Java 21+ toolchain), android (API 24+, compileSdk 34) |
Java NIO & SocketChannel |
| Web & WASM |
wasmWasi (WASI Preview 2 wasi:sockets), wasmJs, js (Node.js & Browser) |
WebAssembly / JS Sockets |
Add socket2-kotlin to your project's build.gradle.kts:
dependencies {
implementation("io.github.kotlinmania:socket2-kotlin:0.2.0")
}Or in a multiplatform project:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.kotlinmania:socket2-kotlin:0.2.0")
}
}
}import io.github.kotlinmania.socket2.Domain
import io.github.kotlinmania.socket2.SocketProtocol
import io.github.kotlinmania.socket2.SockAddr
import io.github.kotlinmania.socket2.Socket
import io.github.kotlinmania.socket2.SocketAddr
import io.github.kotlinmania.socket2.SocketType
import kotlin.time.Duration.Companion.seconds
// Create an IPv4 non-blocking TCP socket
val server = Socket.new(Domain.IPV4, SocketType.STREAM.nonblocking(), SocketProtocol.TCP)
// Fine-grained socket options
server.setReuseAddress(true)
server.setTcpNodelay(true)
server.setKeepalive(true)
server.setSendBufferSize(65536)
server.setRecvBufferSize(65536)
// Bind to local loopback port 8080
val bindAddr = SockAddr.from(SocketAddr.V4("127.0.0.1", 8080))
server.bind(bindAddr)
// Listen with a connection backlog of 128
server.listen(128)
// Accept client connection
val (clientSocket, clientAddr) = server.accept()
println("Client connected from: ${clientAddr.asSocketIpv4()}")val client = Socket.new(Domain.IPV4, SocketType.STREAM, SocketProtocol.TCP)
val destination = SockAddr.from(SocketAddr.V4("93.184.216.34", 80))
// Connect with a 5-second timeout
client.connectTimeout(destination, 5.seconds)
val request = "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n".encodeToByteArray()
client.send(request)val udpSocket = Socket.new(Domain.IPV4, SocketType.DGRAM, SocketProtocol.UDP)
val peerAddr = SockAddr.from(SocketAddr.V4("127.0.0.1", 9000))
val payload = "Hello from KotlinMania!".encodeToByteArray()
udpSocket.sendTo(payload, peerAddr)
val buffer = ByteArray(1024)
val (bytesReceived, sender) = udpSocket.recvFrom(buffer)
println("Received $bytesReceived bytes from $sender")val unixSocket = Socket.new(Domain.UNIX, SocketType.STREAM, null)
val socketPath = SockAddr.unix("/tmp/kotlinmania-ipc.sock")
unixSocket.bind(socketPath)
unixSocket.listen(32)val header = "HTTP/1.1 200 OK\r\nContent-SocketType: text/plain\r\n\r\n".encodeToByteArray()
val body = "Hello, World!".encodeToByteArray()
// Write multiple buffers in a single syscall
val totalWritten = clientSocket.writeVectored(listOf(header, body))socket2-kotlin exports directly into native Swift modules via Kotlin Multiplatform's Swift Export:
import Socket2
let domain = Domain.IPV4
let socketType = SocketType.STREAM
let protocolType = SocketProtocol.TCP
// Directly interact with Socket2 types in Swift# Run unit and integration tests across all targets (includes host tests, WASI node test, and Swift harness)
./gradlew test
# Full multiplatform compilation verification across all 263 target tasks
./gradlew build
# Run static analysis and formatting audits
./gradlew detekt
./gradlew ktlintCheckrust-lang/socket2 authors.