for work, need write server able handle 8000/10000 active connections using tcp protocol.
i've used iocp before, i'm getting weird situation server starts lose events after high load!
to test architecture wrote send-back-everything-you-receive client , server , works fine 1000/2000 clients, when start more connections iocp callback doesn't called!
server , client running on local machine
if put thread.sleep in middle of send/receive events of 1ms works fine , network throughput server can handle goes down lot. tried thread.yield , thread.sleep(0), similar yieald, without useful result.
my development machine i7-3770 8gb of ram, it's able handle load! thread.sleep cpu consumption below 30% , can handle 10000 connections without losing events throughput of 200mbps (client+server) ... when system doesn't lose events, without thread.sleep, server able handle 8gbps throughput!
i'm using 8192 buffer size.
to optimize @ best, code pre-initialize necessary read buffers , read/write socketasynceventargs (in code below there initialization, i've super class extends 1 below , pre-initialize necessary.
here there code of server part
public bool sendasync(byte[] buffer, int offset, int length) { // verifica se è connesso if (this.isconnected == false) { return false; } // attende un eventuale invio in corso this.sendasyncautoresetevent.waitone(); if (this.sendsocketasynceventargs == null) { // inizializza l'oggetto contenente le informazioni per la gestione asincrona (iocp) // dell'invio dei dati this.sendsocketasynceventargs = new socketasynceventargs(); this.sendsocketasynceventargs.completed += new eventhandler<socketasynceventargs>( this.socketasynccallback); } try { this.sendsocketasynceventargs.setbuffer(buffer, offset, length); } catch (objectdisposedexception) { this.sendasyncautoresetevent.set(); return false; } catch (nullreferenceexception) { this.sendasyncautoresetevent.set(); return false; } return this.sendasyncinternal(); } private bool sendasyncinternal() { try { // prova ad avviare la ricezione asincrona if (this.socket.sendasync(this.sendsocketasynceventargs) == false) { // l'operazione si è completata in modo sincrono, gestisce gli eventi this.socketasynccallback(this, this.sendsocketasynceventargs); } } catch (socketexception e) { // imposta l'eccezione this.lastsocketexception = e; this.sendasyncautoresetevent.set(); return false; } catch (objectdisposedexception) { this.sendasyncautoresetevent.set(); return false; } catch (nullreferenceexception) { this.sendasyncautoresetevent.set(); return false; } return true; } protected void socketasynccallback(object sender, socketasynceventargs e) { threadpool.queueuserworkitem(new waitcallback(this.processsocketevent), e); } private void processsocketevent(object state) { socketasynceventargs e = state socketasynceventargs; try { if ( // richiesta chiusura della connessione ( e.lastoperation != socketasyncoperation.connect && e.socketerror == socketerror.success && e.bytestransferred == 0 ) || e.socketerror == socketerror.operationaborted || e.socketerror == socketerror.connectionreset ) { // termina la connessione this.close(); } else if (e.socketerror == socketerror.connectionrefused) { this.processsocketconnectrefused(e); } else { // verifica la presenza di eventuali errori if (e.socketerror != socketerror.success) { throw new exception(e.socketerror.tostring()); } switch (e.lastoperation) { case socketasyncoperation.connect: this.processsocketconnect(e); break; case socketasyncoperation.receive: this.processsocketreceive(e); break; case socketasyncoperation.send: this.processsocketsend(e); this.sendasyncautoresetevent.set(); break; default: break; } } } catch (objectdisposedexception) { // nothing } catch (nullreferenceexception) { // nothing } } private void processsocketconnect(socketasynceventargs e) { this.onconnectionestablished(); } private void processsocketconnectrefused(socketasynceventargs e) { this.onconnectionrefused(); } private void processsocketreceive(socketasynceventargs e) { this.lastpacketrecievedat = datetime.now; this.ondatareceived(e.buffer, e.offset, e.bytestransferred); } private void processsocketsend(socketasynceventargs e) { this.lastpacketsendedat = datetime.now; this.ondatasended(e.buffer, e.offset, e.bytestransferred); }
thanks help!
edit
i forgot specify operating system windows 8 64bit
Comments
Post a Comment