Billie
Erfahrenes Mitglied
Hellas!
Ich experimentiere gerade etwas mit dem NIO-Package (nicht NIO2) und einer "Non Blocking" Client-/Server-Kommunikation.
Also ich habe jetzt folgendet gemacht:
Ich habe mir einen Server geschrieben, der einen internen Buffer von 512 Bytes verwendet. Der Client sendet aber 1.024 Bytes an den Server.
Von diesen Client starte ich ca. 100 Instanzen gleichzeitig.
Mir kommt es jetzt vor, als würde ich pro Request zwei SelectionKey's bekommen. Ich lese also 512 Bytes vom SocketChannel des SelectionKeys, der Channel liefert mir aber dann keine weiteren 512 Bytes und ich arbeite mit dem nächsten Key weiter - von einem anderen Client. Irgendwann bekomme ich dann wieder einen Key vom ersten Client, mit den zweiten 512 Bytes.
Bedeutet das ich muss Daten im Server zwischenspeichern? Woher weiß ich dann dass der Request vom Client jetzt komplett ist?
Folgend einmal meine Testprogramme:
Also, ein NIOClient sendet einen String mit 1.024 Bytes an den Server. Der String besteht aus dem Thread-Namen, wird auf rightPad auf 512 Bytes "gepadded" und zusammengesetzt - sind also 1.024 Bytes.
Am Server lese ich dann jeweils 512 Bytes. Und eigentlich würde ich mir eine Ausgabe wie folgt erwarten:
Die Ausgabe sieht aber eher so aus:
Wie kann ich hier also am Server den Request von einem Client zusammenfassen?
Ich experimentiere gerade etwas mit dem NIO-Package (nicht NIO2) und einer "Non Blocking" Client-/Server-Kommunikation.
Also ich habe jetzt folgendet gemacht:
Ich habe mir einen Server geschrieben, der einen internen Buffer von 512 Bytes verwendet. Der Client sendet aber 1.024 Bytes an den Server.
Von diesen Client starte ich ca. 100 Instanzen gleichzeitig.
Mir kommt es jetzt vor, als würde ich pro Request zwei SelectionKey's bekommen. Ich lese also 512 Bytes vom SocketChannel des SelectionKeys, der Channel liefert mir aber dann keine weiteren 512 Bytes und ich arbeite mit dem nächsten Key weiter - von einem anderen Client. Irgendwann bekomme ich dann wieder einen Key vom ersten Client, mit den zweiten 512 Bytes.
Bedeutet das ich muss Daten im Server zwischenspeichern? Woher weiß ich dann dass der Request vom Client jetzt komplett ist?
Folgend einmal meine Testprogramme:
Java:
public class NIOServer {
private Selector selector = null;
private ServerSocketChannel server = null;
private NIOServer() {
startServer();
}
private void startServer() {
try {
server = ServerSocketChannel.open();
server.configureBlocking(false);
server.socket().bind(new InetSocketAddress(1234));
selector = Selector.open();
SelectionKey sk = server.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
final Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
final SelectionKey selectedKey = keys.next();
keys.remove();
if (selectedKey.isAcceptable()) {
accept(selectedKey);
} else if (selectedKey.isReadable()) {
read(selectedKey);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (server != null) {
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void accept(final SelectionKey key) {
final ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
try {
final SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
} catch (Exception e) {
e.printStackTrace();
}
}
private void read(final SelectionKey key) {
try {
final SocketChannel channel = (SocketChannel) key.channel();
final ByteBuffer buffer = ByteBuffer.allocate(512);
int length = -1;
try {
final StringBuilder sb = new StringBuilder();
buffer.clear();
while ((length = channel.read(buffer)) > 0) {
final byte[] b = new byte[length];
buffer.clear();
buffer.get(b, 0, length);
sb.append(new String(b, 0, length).trim());
}
System.out.println(sb);
} catch (IOException e) {
e.printStackTrace();
}
if (length == -1) {
channel.close();
key.cancel();
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
new NIOServer();
}
}
Java:
public class NIOClient
extends Thread {
public void run() {
SocketChannel client = null;
try {
client = SocketChannel.open();
client.configureBlocking(false);
client.connect(new InetSocketAddress(1234));
Selector selector = Selector.open();
SelectionKey clientKey = client.register(selector, SelectionKey.OP_CONNECT);
while (selector.select(500L) > 0) {
for (final Iterator<SelectionKey> i = selector.selectedKeys().iterator(); i.hasNext(); i
.remove()) {
final SelectionKey key = i.next();
final SocketChannel channel = (SocketChannel) key.channel();
if (channel.isConnectionPending()) {
channel.finishConnect();
}
final String s = StringUtils.rightPad(getName(), 512);
channel.write(ByteBuffer.wrap((s + s).getBytes()));
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (client != null) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new NIOClient().start();
}
}
}
Also, ein NIOClient sendet einen String mit 1.024 Bytes an den Server. Der String besteht aus dem Thread-Namen, wird auf rightPad auf 512 Bytes "gepadded" und zusammengesetzt - sind also 1.024 Bytes.
Am Server lese ich dann jeweils 512 Bytes. Und eigentlich würde ich mir eine Ausgabe wie folgt erwarten:
Code:
Thread-19Thread-19
Thread-85Thread-85
...
Die Ausgabe sieht aber eher so aus:
Code:
Thread-19
Thread-85
Thread-62
Thread-19
Wie kann ich hier also am Server den Request von einem Client zusammenfassen?
Zuletzt bearbeitet von einem Moderator: