Hallo,
ich habe bereits einiges an Erfahrung mit NIO und weiß was ich tue. Ich habe bereits eine Lauffähige Version etc jetzt möchte ich aber Eigehende Verbindungen und Ausgehende Verbindungen mit einem Selector realisieren. Die unterscheidung dieser findet mit zwei verschiedenen Objekten die ich ConnectionKey (als wrapper für SelectionKey mit buffern, nachrichten schlangen, etc) nenne stat. Das is auch nicht das Problem. Jedoch schaffe ich es nicht eine ausgehende Verbindung mit einem Selector zu schaffen...
Dazu jetzt erstmal die Frage:
Kann ein Selector überhaupt als "Server" und als "Client" gleichzeitig agieren? Ich denke schon bin da aber nicht ganz sicher. Dazu ist ja die Unterscheidung connectable (client seite) & acceptable (server seite) da. Mein Ansatz war jetzt einfach mit folgender Methode eine Verbindung auf zu bauen.
Wenn ich dies tue bleibt der Key aber bei dem Selector des Zielservers auf connectable stehen
NOTIZXXX: Hier findet nun folgendes Phänomen statt: beim ersten durchlauf Funktioniert alles, allerdings kann ich den Key nicht auf read oder write umflaggen, weil er laut readyOps nur acceptable ist obwohl ich accept() aufrufe und diese methode einen socketChannel zurück liefert.
Beim zweiten durchgang dann jedoch passiert etwas komisches: Der gleiche key ist immer noch acceptable jedoch gibt die accept() methode nichts mehr (null) zurück. Und der Key ist dann für immer in diesem Zustand und die readyOps veränder sich auch nicht (immer noch 16, OP_ACCEPT).
Irgentwie steh ich hier total auf dem Schlauch oder was ich versuche geht einfach nicht.
ich habe bereits einiges an Erfahrung mit NIO und weiß was ich tue. Ich habe bereits eine Lauffähige Version etc jetzt möchte ich aber Eigehende Verbindungen und Ausgehende Verbindungen mit einem Selector realisieren. Die unterscheidung dieser findet mit zwei verschiedenen Objekten die ich ConnectionKey (als wrapper für SelectionKey mit buffern, nachrichten schlangen, etc) nenne stat. Das is auch nicht das Problem. Jedoch schaffe ich es nicht eine ausgehende Verbindung mit einem Selector zu schaffen...
Dazu jetzt erstmal die Frage:
Kann ein Selector überhaupt als "Server" und als "Client" gleichzeitig agieren? Ich denke schon bin da aber nicht ganz sicher. Dazu ist ja die Unterscheidung connectable (client seite) & acceptable (server seite) da. Mein Ansatz war jetzt einfach mit folgender Methode eine Verbindung auf zu bauen.
Wenn ich dies tue bleibt der Key aber bei dem Selector des Zielservers auf connectable stehen
Java:
protected void connectTo(InetSocketAddress inetSocketAddress) throws IOException {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(inetSocketAddress);
socketChannel.register(this.selector, SelectionKey.OP_CONNECT);
}
Java:
private void onKeyIsAcceptable() {
System.out.println("acceptable...");
// acceptable key; accepting and adding new SocketChannel to
// register for READ only;
this.log("Verbose",
" Acceptable key, accepting and adding new SocketChannel to selector for read only and registering in map",
null);
try {
ServerSocketChannel ssc = (ServerSocketChannel) this.selectionKey.channel();
SocketChannel sc = ssc.accept();
// SIEHE NOTIZ XXX
if (sc == null) {
System.out.println("sc null");
System.out.println(this.selectionKey.readyOps());
return;
}
sc.configureBlocking(false);
sc.socket().setTcpNoDelay(true);
System.out.println(this.selectionKey.readyOps());
} catch (IOException e) {
e.printStackTrace();
this.log("Verbose", "Acceptable key generated IOException, cancelling... " + e.getMessage(), e);
this.connectionKey.cancel();
}
}
private void onKeyIsConnectable() {
// attempting outgoing connection...
System.out.println("connectable...");
// flag this key as an outgoing connection since we initiate the connection
this.connectionKey.setOutgoingConnection(true);
try {
SocketChannel sc = ((SocketChannel) this.selectionKey.channel());
if (sc.finishConnect()) {
System.out.println("connectednow");
}
this.selectionKey.interestOps(SelectionKey.OP_READ);
} catch (IOException e) {
this.log("Verbose",
"Connectable key is cancelled or corrupted, cancelling. " + e.getMessage() + e.getStackTrace(),
e);
e.printStackTrace();
this.connectionKey.cancel();
} catch (NoConnectionPendingException e) {
this.log("Verbose",
"Connectable key is cancelled or corrupted, cancelling. There was no connection pending."
+ e.getMessage() + e.getStackTrace(), e);
this.connectionKey.cancel();
e.printStackTrace();
}
}
NOTIZXXX: Hier findet nun folgendes Phänomen statt: beim ersten durchlauf Funktioniert alles, allerdings kann ich den Key nicht auf read oder write umflaggen, weil er laut readyOps nur acceptable ist obwohl ich accept() aufrufe und diese methode einen socketChannel zurück liefert.
Beim zweiten durchgang dann jedoch passiert etwas komisches: Der gleiche key ist immer noch acceptable jedoch gibt die accept() methode nichts mehr (null) zurück. Und der Key ist dann für immer in diesem Zustand und die readyOps veränder sich auch nicht (immer noch 16, OP_ACCEPT).
Irgentwie steh ich hier total auf dem Schlauch oder was ich versuche geht einfach nicht.