10000 concurrent connection using Java NIO -
i wrote server(similar 1 here) , client code using java nio.
i trying achieve many connections possible. previous suggestions slowed down process of client creation giving os(windows 8) enough time handle requests.
i ran client code on different machine server has available space running.
when try create 10,000 connections around 8500 getting connected , rest refused connection , refusal of connection clients(threads in client code) happens more created later (for loop in client code ).
my cpu , memory usage go drastically high.i profiled see most(48% of total cpu consumption) consumed select method (rest gui events) . due many clients ? saw people complaining bug in jre7 , suggesting use jre6 .
memory usage 2000+ mb javaw.exe
processes.(i noticed 1 process using low memory had major cpu usage ).overall usage around 98% when 8500 or clients connected. system hanged many times continued service.i saw non-page pooled memory usage increased during process 178 mb 310 mb (what max limit ?).is because when write sockets non-page pooled memory used ?
can please tell limits might hitting 10,000 successful connections not possible ? (socket per process limit ?)(non-paged memory ?)(backlog queue again ?) tweaks might able allow limits pushed ? (windows machine)
i using windows 8 on 4gb system.
`
public class server implements runnable { public final static string address = "192.168.2.14"; public final static int port = 8511; public final static long timeout = 10000; public int clients; bytebuffer readbuffer = bytebuffer.allocate(1024); private serversocketchannel serverchannel; private selector selector; private map<socketchannel,byte[]> datatracking = new hashmap<socketchannel, byte[]>(); public server(){ init(); } private void init(){ system.out.println("initializing server"); if (selector != null) return; if (serverchannel != null) return; try { selector = selector.open(); serverchannel = serversocketchannel.open(); serverchannel.configureblocking(false); serverchannel.socket().bind(new inetsocketaddress(address, port)); serverchannel.register(selector, selectionkey.op_accept); } catch (ioexception e) { e.printstacktrace(); } } @override public void run() { system.out.println("now accepting connections..."); try{ while (!thread.currentthread().isinterrupted()){ int ready = selector.select(); if(ready==0) continue; iterator<selectionkey> keys = selector.selectedkeys().iterator(); while (keys.hasnext()){ selectionkey key = keys.next(); keys.remove(); if (!key.isvalid()){ continue; } if (key.isacceptable()){ system.out.println("accepting connection"); accept(key); } if (key.iswritable()){ system.out.println("writing..."); write(key); } if (key.isreadable()){ system.out.println("reading connection"); read(key); } } } } catch (ioexception e){ e.printstacktrace(); } finally{ closeconnection(); } } private void write(selectionkey key) throws ioexception{ socketchannel channel = (socketchannel) key.channel(); byte[] data = datatracking.get(channel); datatracking.remove(channel); **int count = channel.write(bytebuffer.wrap(data)); if(count == 0) { key.interestops(selectionkey.op_write); return; } else if(count > 0) { key.interestops(0); key.interestops(selectionkey.op_read); }** } private void closeconnection(){ system.out.println("closing server down"); if (selector != null){ try { selector.close(); serverchannel.socket().close(); serverchannel.close(); } catch (ioexception e) { e.printstacktrace(); } } } private void accept(selectionkey key) throws ioexception{ serversocketchannel serversocketchannel = (serversocketchannel) key.channel(); socketchannel socketchannel = serversocketchannel.accept(); if(socketchannel == null) { throw new ioexception(); } socketchannel.configureblocking(false); clients++; **//socketchannel.register(selector, selectionkey.op_write|selectionkey.op_read); selectionkey skey = socketchannel.register(selector, selectionkey.op_read);** byte[] hello = new string("hello server").getbytes(); datatracking.put(socketchannel, hello); } private void read(selectionkey key) throws ioexception{ socketchannel channel = (socketchannel) key.channel(); readbuffer.clear(); int length; try { length = channel.read(readbuffer); } catch (ioexception e) { system.out.println("reading problem, closing connection"); system.out.println("no of clients :"+clients); key.cancel(); channel.close(); return; } if (length == -1){ system.out.println("nothing there read, closing connection"); channel.close(); key.cancel(); return; } readbuffer.flip(); byte[] data = new byte[1000]; readbuffer.get(data, 0, length); string fromclient = new string(data,0,length,"utf-8"); system.out.println("received: "+fromclient); string dat = fromclient+channel.getremoteaddress(); data= dat.getbytes(); echo(key,data); } private void echo(selectionkey key, byte[] data) throws ioexception{ socketchannel socketchannel = (socketchannel) key.channel(); datatracking.put(socketchannel, data); **//key.interestops(selectionkey.op_write); try { write(key); } catch(ioexception e) { system.out.println("problem in echo"+e); e.printstacktrace(); } } public static void main(string [] args) { thread serv = new thread(new server()); serv.start(); }
}
socketchannel.register(selector, selectionkey.op_write|selectionkey.op_read);
this incorrect usage. selector spin, op_write
ready, except @ rare times when socket send buffer full. why you're not processing op_accept
fast could. you're busy processing op_write
@ times when have nothing write.
the correct way use op_write
follows:
- register newly accepted channel
op_read
only - when have write channel, write it
- if write returns zero, register channel
op_write
, savebytebuffer
trying write, , return select loop - when
op_write
fires on channel, callwrite()
same buffer - if write succeeds , doesn't return zero, register
op_read
again, or @ least removeop_write
interestops
.
nb closing channel cancels key. don't need cancel.
Comments
Post a Comment