the best practise of udpchannel with selector??
I wrote an module which can send and receive datagrams through UDP.
I use a selector to manage it,but I come with a problem of 100%cpu.
the code is as follows:
private ConcurrentLinkedQueue<ToSendData> resps = new
ConcurrentLinkedQueue<ToSendData>();
...
while (run) {
selector.select();//why it does not block?
if (key.isValid() && key.isReadable()) {
ByteBuffer buffer =
ByteBuffer.allocate(Constant.MAX_RECEIVE_BUFFER_SIZE);
buffer.order(ByteOrder.LITTLE_ENDIAN);
InetSocketAddress sock = (InetSocketAddress) channel.receive(buffer);
if (sock == null)
continue;
receivedDatagramCount++;
log.info("received No." + receivedDatagramCount+ " datagram");
String ip = sock.getAddress().getHostAddress();
int port = sock.getPort();
if (!Crypt.decrypt(buffer.array(), buffer.position())) {
log.warn("=D0=A3=D1=E9=CA=A7=B0=DC=A3=A1");
return;
}
buffer.flip();
P2IHeaderInfo header = P2IHeaderInfo.getInstance(buffer);
buffer.rewind();
DispatchData data = new DispatchData(header, buffer, ip,port,
receivedDatagramCount);
Task task = new Task(Task.DISPATCH, data);
server.sendMessage(task);
}
if (key.isValid() && key.isWritable()) {
if (resps.size() > 0) {
for (ToSendData data = resps.poll(); data != null; data =
resps.poll()) {
if (data.getIp().equals("e")) {
break;
}
String ip = data.getIp();
int port = data.getPort();
ByteBuffer buffer = data.getBuffer();
Crypt.encrypt(buffer.array(), buffer.remaining());
byte[] x = new byte[buffer.remaining()];
System.arraycopy(buffer.array(), 0, x, 0, buffer.remaining());
sendDatagramCount++;
log.info("Server sends No." + sendDatagramCount+ " datagram: ");
channel.send(buffer,new InetSocketAddress(ip, port));
}
}
// If uncomment these block,the cpu goes 100%
// else{
// Thread.sleep(1);
// }
}
}
It seems that udpchannel is always writable and it won't block these
thread any bit,
I think maybe I need another thread to send datagrams and use a
LinkedBlockingQueue instead of ConcurrentLinkedQueue.
What is the best practice of making this module?