ProductPromotion
Logo

Kotlin

made by https://0x3d.site

GitHub - seniorjoinu/reliable-udp: Multiplexed, coroutine-powered reliable UDP for Kotlin using fountain codes
Multiplexed, coroutine-powered reliable UDP for Kotlin using fountain codes - seniorjoinu/reliable-udp
Visit Site

GitHub - seniorjoinu/reliable-udp: Multiplexed, coroutine-powered reliable UDP for Kotlin using fountain codes

GitHub - seniorjoinu/reliable-udp: Multiplexed, coroutine-powered reliable UDP for Kotlin using fountain codes

Reliable UDP

Build Status

Quick example

// create a pair of sockets
val rudp1 = RUDPSocket()
val rudp2 = RUDPSocket()

val net1Addr = InetSocketAddress(1337)
val net2Addr = InetSocketAddress(1338)

// bind to some address
rudp1.bind(net1Addr)
rudp2.bind(net2Addr)

val net1Content = ByteArray(20000) { it.toByte() }

// running coroutines in some scope (as you might notice, it uses only one thread)
runBlocking {
    // start sockets
    launch { rudp1.runSuspending() }
    launch { rudp2.runSuspending() }

    // send-receive some stuff
    coroutineScope {
        launch { rudp1.send(net1Content, net2Addr) }
        launch { rudp1.send(net1Content, net2Addr) }
        launch { rudp2.receive() }
        launch { rudp2.receive() }
    } 
    // <-- at this moment all send() and receive() are completed, thanks to the structured concurrency

    // stop sockets
    coroutineContext.cancelChildren()
}

// close sockets, free resources
rudp1.close()
rudp2.close()

What's inside

  1. The main idea is to provide super-flexible and super-fast reliable udp transport that is easy to use.
  2. Design is something like event loop that you can control. So no billion threads/coroutines until you really want it. RUDP is thread-safe and supports multiplexing by default.
  3. It uses fountain codes so no real ARQ is performed. This makes RUDP (in theory) superior to TCP and maybe to kcp.
  4. API is almost the same as in standard DatagramSocket. There is no connections and other boring stuff (actually there are, but they are inside). MTU, WINDOW_SIZE and other stuff is configurable as in kcp.
  5. RUDPSocket uses only one port to receive and send data.

// TODO: add AWS benchmark

API Reference

/**
 * The socket itself. Just create one of those and use it to send and receive data over the network.
 *
 * @param mtuBytes [Int] - minimum MTU of all those router between you and someone you send data to
 * @param windowSizeBytes [Int] - pieces of data are sent in small groups with total size of this value
 * @param congestionControlTimeoutMs [Long] - after each group of [windowSizeBytes] is sent, socket waits until
 *  [congestionControlTimeoutMs] elapsed before sending another [windowSizeBytes] of that data
 * @param cleanUpTimeoutMs [Long] - the lesser this value is, the more frequent socket will clean up itself
 */
class RUDPSocket(
    val mtuBytes: Int = 1200,
    val windowSizeBytes: Int = 4800,
    val congestionControlTimeoutMs: Long = 100,
    val cleanUpTimeoutMs: Long = 1000 * 60 * 10
)

/**
 * Binds to the local address. Before this call you're unable to receive packets.
 *
 * @param on [InetSocketAddress] - address to bind
 */
fun RUDPSocket.bind(on: InetSocketAddress)

/**
 * Destroys all contexts and closes this socket - after this you should create another one to work with
 */
fun RUDPSocket.close()

/**
 * Is socket closed
 *
 * @return [Boolean]
 */
fun RUDPSocket.isClosed(): Boolean

/**
 * Adds data in processing queue for send. Suspends until data is certainly sent. Can be canceled.
 *
 * @param data [ByteBuffer] - normalized (flipped) data
 * @param to [InetSocketAddress] - address to send data to
 *
 * @return [RUDPSendContext]
 */
suspend fun RUDPSocket.send(data: ByteBuffer, to: InetSocketAddress): RUDPSendContext

/**
 * [RUDPSocket.send] but instead of [ByteBuffer] it sends [ByteArray]
 *
 * @param data [ByteArray] - input data
 * @param to [InetSocketAddress] - receiver
 *
 * @return [RUDPSendContext]
 */
suspend fun RUDPSocket.send(data: ByteArray, to: InetSocketAddress): RUDPSendContext

/**
 * Suspends until there is a packet to receive
 *
 * @return [QueuedDatagramPacket]
 */
suspend fun RUDPSocket.receive(): QueuedDatagramPacket

/**
 * Executes [RUDPSocket.runOnce] in loop until coroutine is not canceled
 */
suspend fun RUDPSocket.runSuspending()

/**
 * Runs processing loop once. Suspends if nobody receives packets.
 *
 * Loop consists of three stages:
 *  1. Clean up
 *  2. Processing send
 *  3. Processing receive
 */
suspend fun RUDPSocket.runOnce()

Algorithm in short words

  1. Sender adds data to the send queue socket.send(data, address)
  2. When socket.runOnce() is invoked
    1. Source data is transformed into small portion of repair packets
    2. Repair packets are written to DatagramSocket sequentially
    3. If there are packets to read from DatagramSocket they are read
    4. For each read repair packet it tries to restore source data
    5. If data is restored completely, ACK packet sent back to sender and data is added to the receive queue
  3. Receiver tries to receive data from the receive queue socket.receive()

Installation

Use Jitpack

Examples

For example usage in other app see integration-example-project

For advanced usage see seniorjoinu/prodigy

Also see test dir in this repo

Contribution

If you want to improve RUDP but don't know where to start, there is a project. Pick any task you like and propose a PR.

More Resources
to explore the angular.

mail [email protected] to add your project or resources here 🔥.

Related Articles
to learn about angular.

FAQ's
to learn more about Angular JS.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory