working suspended TCP block device on JVM (server and client)
This commit is contained in:
1 parent
fe29bec1b0
commit
1814572a04
7 files changed
+71
-22
No files matched your search
@@ -4,19 +4,35 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.SendChannel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.sergeych.kiloparsec.Transport
|
||||
import java.net.InetAddress
|
||||
import java.net.InetSocketAddress
|
||||
import java.nio.channels.AsynchronousServerSocketChannel
|
||||
import java.nio.channels.AsynchronousSocketChannel
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
actual fun NetworkAddress(host: String, port: Int): NetworkAddress =
|
||||
JvmNetworkAddress(InetAddress.getByName(host), port)
|
||||
|
||||
actual fun acceptTcpDevice(pord: Int): Flow<Transport.Device> {
|
||||
actual fun acceptTcpDevice(port: Int): Flow<Transport.Device> {
|
||||
return flow {
|
||||
|
||||
TODO("Not yet implemented")
|
||||
println("start generating tcp accept flow")
|
||||
val socket = withContext(Dispatchers.IO) {
|
||||
AsynchronousServerSocketChannel.open().also {
|
||||
it.bind(InetSocketAddress(InetAddress.getLocalHost(), port))
|
||||
}
|
||||
}
|
||||
println("Server socket ready $socket")
|
||||
val connectedSocket = suspendCancellableCoroutine { continuation ->
|
||||
continuation.invokeOnCancellation {
|
||||
socket.close()
|
||||
}
|
||||
socket.accept(continuation, ContinuationHandler())
|
||||
}
|
||||
println("incoming connection")
|
||||
emit(asyncSocketToDevice(connectedSocket))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,5 +49,5 @@ actual suspend fun connectTcpDevice(address: NetworkAddress): Transport.Device {
|
||||
}
|
||||
|
||||
suspend fun SendChannel<UByte>.sendAll(bytes: Collection<UByte>) {
|
||||
for( b in bytes) send(b)
|
||||
for (b in bytes) send(b)
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import net.sergeych.crypto.encodeVarUnsigned
|
||||
import net.sergeych.crypto.readVarUnsigned
|
||||
import net.sergeych.crypto.toDump
|
||||
import net.sergeych.kiloparsec.Transport
|
||||
import net.sergeych.mp_tools.globalLaunch
|
||||
import java.nio.ByteBuffer
|
||||
@@ -38,21 +39,22 @@ suspend fun asyncSocketToDevice(socket: AsynchronousSocketChannel): Transport.De
|
||||
val size: Int = suspendCoroutine { continuation ->
|
||||
socket.read(inb, continuation, IntCompletionHandler)
|
||||
}
|
||||
println("--------- read chunk $size")
|
||||
if (size < 0) stop()
|
||||
else for (i in 0..<size) input.send(inb[i].toUByte().also { print(it.toInt().toChar())})
|
||||
}
|
||||
}
|
||||
// copy from output tp socket
|
||||
launch {
|
||||
val outb = ByteBuffer.allocate(1024)
|
||||
val outBuff = ArrayList<Byte>(1024)
|
||||
try {
|
||||
while (isActive) {
|
||||
var count = 0
|
||||
outb.put(count++, output.receive().toByte())
|
||||
while (!output.isEmpty && count < outb.capacity())
|
||||
outb.put(count++, output.receive().toByte())
|
||||
outBuff.clear()
|
||||
outBuff.add(output.receive().toByte())
|
||||
while (!output.isEmpty)
|
||||
outBuff.add(output.receive().toByte())
|
||||
suspendCoroutine { continuation ->
|
||||
socket.write(outb, continuation, IntCompletionHandler)
|
||||
socket.write(ByteBuffer.wrap(outBuff.toByteArray()), continuation, IntCompletionHandler)
|
||||
}
|
||||
}
|
||||
} catch (_: ClosedReceiveChannelException) {
|
||||
@@ -65,12 +67,14 @@ suspend fun asyncSocketToDevice(socket: AsynchronousSocketChannel): Transport.De
|
||||
try {
|
||||
while (isActive) {
|
||||
val size = readVarUnsigned(input)
|
||||
println("expected size $size")
|
||||
if (size == 0u) println("*** zero size block is ignored!")
|
||||
else {
|
||||
val block = UByteArray(size.toInt())
|
||||
for (i in 0..<size.toInt()) {
|
||||
block[i] = input.receive()
|
||||
}
|
||||
println("ready block:\n${block.toDump()}")
|
||||
inputBlocks.send(block)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user