переписываю древний проект, используется java.nio
//корутина
val serverIPAddress = InetAddress.getByName(serverAddressString)
val serverAddress = InetSocketAddress(serverIPAddress, serverPort)
val selector = Selector.open()
val channel = SocketChannel.open()
channel.configureBlocking(false)
val channelConnectResult = channel.connect(serverAddress) // тут всегда false
Timber.d("channel.connect: $channelConnectResult")
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<1000) {
delay(50)
count++
}
if (channel.finishConnect()) {
Timber.d("channel.finishConnect() IS TRUE, count: $count") //тут count == 2 или 3
_connectionState.emit(ConnectionState.Connected())
} else {
Timber.e("channel.finishConnect() IS FALSE")
cancel()
}
но с сервера ничего не приходит
старый код который работает
public void connect() throws IOException {
Log.d(TAG, "connect() called, Address: " + serverAddress + ", port: " + serverPort);
InetAddress serverIPAddress = InetAddress.getByName(serverAddress);
int port = serverPort;
InetSocketAddress serverAddress = new InetSocketAddress(serverIPAddress, port);
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(serverAddress);
selector = Selector.open();
int operations = SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE;
try {
lock.lock();
selector.wakeup();
channel.register(selector, operations);
} finally {
lock.unlock();
}
socket = channel.socket();
socketThread = new SocketThread();
socketThread.start();
}
private class SocketThread extends Thread {
@Override
public void run() {
Log.d(TAG, "SocketThread run called");
try {
Log.d(TAG, "SocketThread run, selector: " + selector);
Log.d(TAG, "SocketThread run, isInterrupted(): " + currentThread().isInterrupted());
if (selector != null) {
while (!currentThread().isInterrupted()) {
if (selector.select(50) > 0) {
//Log.d(TAG, "SocketThread selector.select() IS NOT ZERO");
boolean doneStatus = processReadySet(selector.selectedKeys());
if (doneStatus) {
break;
}
}
}
Log.d(TAG, "SocketThread run, isInterrupted(): " + currentThread().isInterrupted());
}
} catch (DisconnectException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
disconnect();
} catch (IOException e) {
e.printStackTrace();
} finally {
App.getInstance().setSocketClient(null);
connectionCallback.onConnectionState(EConnectionState.DISCONNECTED);
}
}
}
}
public boolean processReadySet(Set readySet) throws Exception {
//Log.d(TAG, "processReadySet called");
Iterator iterator = readySet.iterator();
while (iterator.hasNext()) {
//Log.d(TAG, "iterator.hasNext(): " + iterator.hasNext());
SelectionKey key = (SelectionKey) iterator.next();
iterator.remove();
//Android's Socket.isConnected() will return true instead of false if the Socket was disconnected incorrectly (i.e. not calling Socket.close).
//I think the only guaranteed way of knowing if a Socket is still alive is to try to write to it and
// handle the IOException that it will throw if it is not connected.
if (key.isConnectable() && !socket.isConnected()) {
Log.d(TAG, "key.isConnectable()");
boolean connected = processConnect(key);
if (!connected) {
return true; // Exit
} else {
connectionCallback.onConnectionState(EConnectionState.CONNECTED);
}
}
if (key.isReadable()) {
Log.d(TAG, "key.isReadable()");
byte[] data = processRead(key);
connectionCallback.onIncomingData(data);
}
if (key.isWritable()) {
//Log.d(TAG, "key.isWritable()");
try {
locker.lock();
if (dataOut != null) {
processWrite(key, dataOut);
dataOut = null;
}
} finally {
locker.unlock();
}
}
}
return false; // Not done yet
}