NIO: problem med read fra SocketChannel til ByteBuffer
Jeg har en server der gør anvendelse af multiplexed, non-blocking I/O med java.nio. Når klienter connecter venter serveren på beskeden: <system cmd="knock"/>, returnerer en besked og disconncter klienten. Klienten serviceres kort på under et sekund.Men i 20% af tilfældene modtager serveren aldrig noget fra klienterne - også selvom de med garanti har sendt. Eller med andre ord: serveren modtager og data bliver placeret i en ByteBuffer - SocketChannel.read(ByteBuffer) - men et kald til ByteBuffer.remaing() returnerer 0 !!
ByteBuffer receiveBuf = ByteBuffer.allocate(65536);
receiveBuf.clear(); // koden anvendes andre steder til længere levende klienter
int readBytes = channel.read(receiveBuf);
receiveBuf.flip();
StringBuffer sb = new StringBuffer();
System.out.println(" * Remaining: "+receiveBuf.remaining()); // skriver: ' * Remaining: 0'
System.out.println(" * Received: "+new String(receiveBuf.array())); // skriver: ' * Received: <system cmd="knock"/>'
while(receiveBuf.remaining() >= 2) {
byte b = receiveBuf.get();
sb.append((char)b);
}
System.out.println(" * sb content: "+sb.toString()); // writes: ' * sb content: '
ByteBuffer'en modtager klart de korrekte data, men ByteBuffer.remaining() returnerer 0 og derfor får StringBuffer'en ikke fyldt noget i sig.
Problemet forekommer tilfældigt, nogen gange mange gange i træk og andre gange med lange intervaller, men stadig i 20% af tilfældene. Klienterne køres simuleret fra samme PC
Nogen der ved hvad der lige går galt her, og hvordan problemet løses?
Jeg har prøvet at fjerne linien - receiveBuf.clear(); - hvilket resulterer i at ByteBuffer.remaining() IKKE returnerer 0, men over. Fejlen forekommer ligeså ofte og består i så fald i, at det sidste tegn i modtagede data mangler: <system cmd="knock"/
