c# - Losing events using IOCP Sockets on high load -


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