переписываю древний проект, используется сокет из java.nio
в некоторый момент адрес сервера может измениться и надо пересоздать соединение, но channel.finishConnect() всегда false
для тестирования соединяюсь по тому же адресу, может быть в этом проблема? сервер считает старый сокет открытым?
есть корутина
fun createNioSocket(serverAddressString: String, serverPort: Int) {
job?.cancel()
job = scope.launch(Dispatchers.IO) {
val serverIPAddress = InetAddress.getByName(serverAddressString)
val serverAddress = InetSocketAddress(serverIPAddress, serverPort)
var channel: SocketChannel? = null
var selector: Selector? = null
try {
channel = SocketChannel.open()
channel.configureBlocking(false)
val channelConnectResult = channel.connect(serverAddress)
Timber.d("channel.connect: $channelConnectResult")
selector = Selector.open()
val operations = SelectionKey.OP_CONNECT or SelectionKey.OP_READ or SelectionKey.OP_WRITE
//selector.wakeup();
val selectionKey = channel.register(selector, operations)
var count = 0
while (!channel.finishConnect() && count < 100) {
delay(50)
count++
}
if (channel.finishConnect()) {
Timber.d("channel.finishConnect() IS TRUE, count: $count")
_connectionState.emit(ConnectionState.Connected())
} else {
Timber.e("channel.finishConnect() IS FALSE") // <--------------при повторном запуске попадаем сюда всегда
cancel()
}
while (isActive) {
selector.select(50)
val iterator: MutableIterator<SelectionKey> = selectionKey.selector().selectedKeys().iterator()
while (iterator.hasNext()) {
val key = iterator.next()
iterator.remove()
if (isActive && key.isReadable) {
//Timber.d("key.isReadable()")
try {
val data: ByteArray = processRead(key)
if (data.isNotEmpty()) {
onIncomingData(data)
}
} catch (e: DisconnectException) {
Timber.e("DisconnectException while processRead")
cancel()
}
}
if (isActive && key.isWritable) {
//Timber.d("key.isWritable()");
sendMutex.withLock {
try {
if (dataOut.isNotEmpty()) {
processWrite(key, dataOut)
dataOut = ByteArray(0)
}
} catch (e: DisconnectException) {
Timber.e("DisconnectException while processWrite")
cancel()
}
}
}
}
}
} finally {
Timber.d("job finally")
val socket: Socket? = channel?.socket()
try {
Timber.d("job finally, channel: $channel")
channel?.close()
Timber.d("1 job finally, selector: $selector, .isOpen: ${selector?.isOpen} ") //true
Timber.d("1 job finally, socket: $socket, .isClosed ${socket?.isClosed}") //true
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
try {
Timber.d("job finally, selector: $selector")
selector?.close()
Timber.d("2 job finally, selector: $selector, .isOpen: ${selector?.isOpen} ") //false
Timber.d("2 job finally, socket: $socket, .isClosed ${socket?.isClosed}") //true
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
try {
Timber.d("job finally, socket: $socket")
socket?.close()
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
dataOut = ByteArray(0)
dataIn.setLength(0)
_connectionState.emit(ConnectionState.Disconnected())
}
}
останавливается
fun disconnect() {
Timber.d("disconnect() called")
job?.cancel()
}