Hey guys, I'm currently trying to write a TCP pro...
# ktor
b
Hey guys, I'm currently trying to write a TCP proxy with KTor, however I'm having some trouble reading from one
ByteReadChannel
and copying those bytes over and Writing to another
ByteWriteChannel
The proxy should tunnel connections from client A to server B via proxy server C like so:
A <---> C <---> B
currently, I have something like the following:
Copy code
//some boilerplate to open correct channels and establish socket connections
val clientReadChannel = clientSocket.openReadChannel()
val clientWriteChannel = clientSocket.openWriteChannel(true)

val serverReadChannel = serverSocket.openReadChannel()
val serverWriteChannel = serverSocket.openWriteChannel(true)

launch(<http://Dispatchers.IO|Dispatchers.IO>) {
    clientReadChannel.copyTo(serverWriteChannel)
}

launch(<http://Dispatchers.IO|Dispatchers.IO>) {
    serverReadChannel.copyTo(clientWriteChannel)
}
And this works perfectly fine, but what I really want to accomplish is to be able to do some work on the underlying Channels ByteBuffer streams before I send them out to the respective client or server.
(possibly even modifying the underlying buffer if necessary)
I've tried something like the following:
Copy code
val clientReadChannel = clientSocket.openReadChannel()
val clientWriteChannel = clientSocket.openWriteChannel(true)

val serverReadChannel = serverSocket.openReadChannel()
val serverWriteChannel = serverSocket.openWriteChannel(true)

launch(<http://Dispatchers.IO|Dispatchers.IO>) {
    clientReadChannel.read {
        launch(<http://Dispatchers.IO|Dispatchers.IO>) { serverWriteChannel.writeAvailable(it) }
    }
}
launch(<http://Dispatchers.IO|Dispatchers.IO>) {
    serverReadChannel.read {
        launch(<http://Dispatchers.IO|Dispatchers.IO>) { clientWriteChannel.writeAvailable(it) }
    }
}
But it only reads once and writes once then stops and when I put the
clientReadChannel
or the
serverReadChannel
in a while loop I get some wildly bizarre behaviour where the same packet gets read multiple times
any ideas? Thanks 🙂
a
You can allocate a buffer, write data to it by reading from a channel, modify it and then write it to an outbound channel. Here is an example:
Copy code
launch(<http://Dispatchers.IO|Dispatchers.IO>) {
    val buffer = ByteBuffer.allocateDirect(32 * 1024)

    while (serverReadChannel.readAvailable(buffer) > 0) {
        buffer.flip()
        // Modify buffer here
        clientWriteChannel.writeFully(buffer)
        buffer.clear()
    }
}
👍 1
b
Ill try this out in a bit, thanks!
ill post here again, if I have any troubles
175 Views