Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to disable forcibly closed by the remote host? #1801

Open
ronjunevaldoz opened this issue Apr 17, 2020 · 2 comments
Open

How to disable forcibly closed by the remote host? #1801

ronjunevaldoz opened this issue Apr 17, 2020 · 2 comments
Assignees
Labels

Comments

@ronjunevaldoz
Copy link

ronjunevaldoz commented Apr 17, 2020

Ktor Version and Engine Used (client or server and name)
implementation "io.ktor:ktor-network:1.3.2"

Describe the bug
Using the raw socket example. My existing client (untouchable) is having a duplication connection which is a known issue on client side. But the server is forcibly closing the client connection. I've added some custom socket options to keep alive but it does not work. The coroutine is cancelling when there is an existing connection

 /**
     * Set TCP_KEEP_ALIVE socket option to enable the Nagle algorithm.
     */
    private fun <T : Configurable<T, *>> T.tcpKeepAlive(): T {
        return configure {
            if (this is SocketOptions.TCPClientSocketOptions) {
                keepAlive = true
            }
        }
    }

To Reproduce
Simple echo server example from https://ktor.io/servers/raw-sockets.html

fun main(args: Array<String>) {
    runBlocking {
        val server = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().bind(InetSocketAddress("127.0.0.1", 2323))
        println("Started echo telnet server at ${server.localAddress}")
        
        while (true) {
            val socket = server.accept()
            
            launch {
                println("Socket accepted: ${socket.remoteAddress}")
                
                val input = socket.openReadChannel()
                val output = socket.openWriteChannel(autoFlush = true)
                
                try {
                    while (true) {
                        val line = input.readUTF8Line()
                        
                        println("${socket.remoteAddress}: $line")
                        output.write("$line\r\n")
                    }
                } catch (e: Throwable) {
                    e.printStackTrace()
                    socket.close()
                }
            }
        }
    }
}

Expected behavior
I could have handle the server, whether I choose to force close or not, when having a duplicate connection

Raw Error

Exception in thread "DefaultDispatcher-worker-6" java.io.IOException: An existing connection was forcibly closed by the remote host
	at sun.nio.ch.SocketDispatcher.read0(Native Method)
	at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43)
	at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
	at sun.nio.ch.IOUtil.read(IOUtil.java:192)
	at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
	at io.ktor.utils.io.nio.ChannelsKt.read(Channels.kt:135)
	at io.ktor.network.sockets.CIOReaderKt$attachForReadingDirectImpl$1$1$1.invokeSuspend(CIOReader.kt:90)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:175)
	at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:137)
	at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:108)
	at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:306)
	at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:316)
	at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:248)
	at io.ktor.network.selector.SelectorManagerSupport.handleSelectedKey(SelectorManagerSupport.kt:84)
	at io.ktor.network.selector.SelectorManagerSupport.handleSelectedKeys(SelectorManagerSupport.kt:64)
	at io.ktor.network.selector.ActorSelectorManager.process(ActorSelectorManager.kt:73)
	at io.ktor.network.selector.ActorSelectorManager$process$1.invokeSuspend(ActorSelectorManager.kt)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
@e5l e5l self-assigned this Apr 20, 2020
@oleg-larshin
Copy link

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

@Stexxe
Copy link
Contributor

Stexxe commented Jul 27, 2021

@ronjunevaldoz could you please describe the steps to reproduce this problem using your code example?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants