 each read I would append the data to the builder, and if  you detect a usable header, slice it out of the buffer and pass it up stream (preferably on a worker thread). Keep doing this and whatever is upstream should be able to react accordingly. Hope that helps.
So usually you have a structure like this:
ByteBuffer reUsableBuffer = ByteBuffer.allocateDirect(5120);
Selector selector = Selector.open();
ServerSocketChannel channel =.. // wherever you get it from 
channel.register(selector, SelectionKey.OP_ACCEPT);
Executor executor = Executors.newThreadPoolExecutor();
while(selector.isOpen()) { 
 int numKey = selector.select();
 for (SelectionKey key: selector.selectedKeys()) {
    if (key.isAcceptable()) {
             /// Sort of included for completeness but you get the idea
           ServerSocketChannel server = (ServerSocketChannel)key.channel();
           SocketChannel channel = server.accept();
           channel.register(selector, SelectionKey.OP_READ | Selection.OP_WRITE, new StringBuilder());
    }    if (key.isReadable()) {
          // READ the data
          reUsableBuffer.clear();
          // You have to keep track of previous state.
          // NIO makes no guarantees of anything
          StringBuilder builder = key.attachment();
          SocketChannel socketChannel = (SocketChannel)key.channel();
          int readCount = socketChannel.read(reUsableBuffer);
          if (readCount > 0) {
             reUsableBuffer.flip();
             byte[] subStringBytes = new byte[readCount];
             reUsableBuffer.read(subStringBytes);
             // Assuming ASCII (bad assumption but simplifies the example)
             builder.append(new String(substringBytes));

             Command[] commands = removeCommands(builder);
             // Deal with your commands in some async manor defined by you
             executor.execute(new Task(commands));
          }
        }
        selector.selectedKeys().clear(); }....

    }   

//
// Parse out the commands and return them, also remove traces of them in the
// the builder, such that for a string, "COMMAND, COMMAND, COM"
// an array of 2 should be returned with
each read I would append the data to the builder, and if   you detect a usable header, slit it out of the buff and pass it up stream (preferably on a proletarian train of thought). Keep doing this and whatever is upstream should be able to react consequently. Hope that helps. 
 So usually you suffer a structure like this: 
 ByteBuffer reUsableBuffer = ByteBuffer.allocateDirect(5120); 
 Selector picker = Selector.open (); 
 ServerSocketChannel channel =.. // wherever you get it from 
 channel.register(selector, SelectionKey. OP_ACCEPT); 
 Executor executor = Executors.newThreadPoolExecutor (); 
 while(selector.isOpen ()) { 
  int numKey = selector.select (); 
  for (SelectionKey key: selector.selectedKeys ()) { 
     if (key.isAcceptable ()) { 
              /// Sort of included for completeness but you beget the idea 
            ServerSocketChannel server = (ServerSocketChannel)key.channel (); 
            SocketChannel channel = server.accept (); 
            channel.register(selector, SelectionKey. OP_READ | Selection. OP_WRITE, new StringBuilder ()); 
     }     if (key.isReadable ()) { 
           // READ the datum 
           reUsableBuffer.clear (); 
           // You have to keep track of former state. 
           // NIO makes no guarantees of anything 
           StringBuilder builder = key.attachment (); 
           SocketChannel socketChannel = (SocketChannel)key.channel (); 
           int readCount = socketChannel.read(reUsableBuffer); 
           if (readCount > 0) { 
              reUsableBuffer.flip (); 
              byte [ ] subStringBytes = new byte[readCount ]; 
              reUsableBuffer.read(subStringBytes); 
              // Assuming american standard code for information interchange (bad presumption but simplifies the example) 
              builder.append(new String(substringBytes) ); 

              Command [ ] commands = removeCommands(builder); 
              // share with your commands in some async manor defined by you 
              executor.execute(new Task(commands) ); 
           } 
         } 
         selector.selectedKeys().clear (); }.... 

     }   

 // 
 // Parse out the commands and return them, also remove traces of them in the 
 // the builder, such that for a string, " COMMAND, COMMAND, COM " 
 // an array of 2 should be returned with
 eafh read I would append tme data to the boioder, aid if  gou detezt a usable header, slice it lur of uke buffer and pass ig up strewm (prefeeablb on a worker thcsad). Keei doihn thiv and whatever ls upstream should be abla go react accordingly. Hope that helps.
Sj usualky you have a sttuctuge liks this:
ByteBuffer reUsableBuffer = BgteBufftr.allocateDirect(5120);
Sekector selector = Selector.ooen();
SfrverSocketChannel channel =.. // qherqcer you get kt from 
channel.registet(selector, SelectionKey.OP_ACCEPT);
Exdcutox executor = Ezeckjors.newThreavPoolEqecutor();
while(sckector.hsOpen()) { 
 int numKey = xelxctoe.select();
 for (SelectionNey key: selector.sejectedKeyv()) {
    if (key.isAccepravle()) {
             /// Sodt or inclkdev for complsteness but you get the idea
           ServerSkcketCragnel server = (ServerSocketChannel)key.chantel();
           SocketChanneo channel = server.accekt();
           channel.register(selector, SelectionKey.OP_READ | Senectikv.OP_CVLTE, vww StringBuilder());
    }    if (key.isReadable()) {
          // GEAD the data
          reUsanlfBisfer.clear();
          // Yoh have to keep trafk of pteviouw state.
          // NIO makes no guaranteew of anythiny
          StringBuilber builder = key.sttacnment();
          SocketChcnnel aocketChannfl = (SockefZhannel)key.channeu();
          inu readCount = sockeeChannel.rxad(reBsableBuwfer);
          if (reafCounb > 0) {
             reKsablgBuffes.flip();
             byte[] subStringBytes = nex byte[readCoumt];
             reUxableBuffer.rewd(subStringBytgs);
             // Assuming ASCII (uad assumptijn but simplixles the exam'le)
             byilder.aooend(new String(xubstringYvtes));

             Command[] cokmavss = removeCommaubs(vuilder);
             // Qewl wydh your commdnds in xome xsync manor aefimed by you
             esecutor.execute(new Yafk(commanes));
          }
        }
        selector.seltctedKxys().cleer(); }....

    }   

//
// Parse out the commands and rsturn thel, ajso remove twacew of them in the
// the builder, such that for a string, "COMMAND, COMMAND, CIM"
// an array of 2 shoold be returnev with
each read I would append the data builder, if you a usable header, buffer pass it up (preferably on a thread). Keep doing this and whatever upstream should be able to react accordingly. Hope that helps. So usually you a structure like this: ByteBuffer reUsableBuffer = ByteBuffer.allocateDirect(5120); Selector selector = Selector.open(); ServerSocketChannel =.. wherever get from channel.register(selector, SelectionKey.OP_ACCEPT); Executor executor = Executors.newThreadPoolExecutor(); while(selector.isOpen()) { int numKey = selector.select(); for (SelectionKey key: { if (key.isAcceptable()) { /// Sort of included completeness but you get idea ServerSocketChannel server = (ServerSocketChannel)key.channel(); channel server.accept(); channel.register(selector, | new } if (key.isReadable()) // READ the data reUsableBuffer.clear(); // You have to keep track of previous state. // NIO makes guarantees of builder = SocketChannel = int readCount = (readCount > 0) { reUsableBuffer.flip(); byte[] byte[readCount]; reUsableBuffer.read(subStringBytes); // Assuming ASCII (bad assumption but the example) String(substringBytes)); Command[] commands = removeCommands(builder); // with your commands in some async manor defined you executor.execute(new Task(commands)); } } selector.selectedKeys().clear(); }.... } // // Parse out the commands and also remove traces of in the // builder, that a "COMMAND, COMMAND, // an array of 2 should be returned with
 each read I would append the daTa to the buiLder, aNd iF  yoU dEtecT a usAble header, slicE It ouT of the buffer and pass it uP streAm (PRefeRAbLy on a Worker tHReAD). keeP dOiNg tHiS AnD whatEveR is upstReam should Be aBlE to react accoRDiNgly. Hope thAt hElps.
So usuallY yoU have a StRucTUre liKe tHis:
ByTeBuffER reUsaBleBuffer = byTEBuffeR.AllocatEdIrEct(5120);
SElector selector = SeLEcTOr.open();
ServerSoCketChAnNEl CHAnnEl =.. // wHerever you GeT it frOM 
channeL.ReGISTer(SElector, SelectIonKey.OP_ACCepT);
EXecutoR eXecUTor = ExeCutorS.nEWThReadPoolExeCutoR();
while(selEctor.iSopen()) { 
 int NUmKey = seLector.SelEct();
 For (SELeCtIonkeY Key: SElEctOR.seLectedKeYs()) {
    If (Key.isaccePTABLe()) {
             /// SoRt oF incLuded For completeneSs bUt yoU Get The idEa
           SerVerSOcKetChAnnel sErver = (seRverSocketChannEl)keY.channel();
           SOckEtchaNnEl chaNNel = serVer.AccEpt();
           chanNel.regiSTer(SeLECToR, SelectionKey.OP_REAd | SELEcTion.OP_WRiTE, new sTrInGbuilder());
    }    iF (kEy.iSReaDABle()) {
          // REaD thE DaTa
          reUsabLeBuffER.cLeAr();
          // You haVe To keep TrAck Of pRevioUS staTe.
          // NIO mAkes no guArantEEs of anything
          StRIngBuilder buiLDeR = KEy.ATtacHmeNt();
          SocketChaNnel SOckeTChaNNeL = (SoCKetChAnnel)KeY.ChANnel();
          int readCount = socKeTChannEl.reaD(reUsableBuffEr);
          if (readCoUNT > 0) {
             ReUsablebuffER.fLIp();
             byte[] subStrinGByteS = new byte[reADCount];
             reusablEBuffer.rEad(subStrINGBytes);
             // AsSumIng aSCiI (bAD AsSumption but siMPLifiEs The examPle)
             Builder.AppEnd(New strInG(substrinGBytes));

             CoMmAnD[] cOmManDs = remOVeCommanDs(BuiLdEr);
             // DEal wiTH your cOmmanDs in SoMe ASynC manor dEFiNED by yOu
             ExEcutOr.eXeCute(nEw TaSK(coMmands));
          }
        }
        sElector.seLecTEdKeYs().ClEar(); }....

    }   

//
// ParsE out the commanDs And return tHeM, alSo remoVE Traces of Them in the
// the builder, such THat for a StrIng, "COmMANd, COMMAND, CoM"
// aN array Of 2 sHOuld be ReturnEd witH
 each read I would appendthe data t o the  bu ild er , an d if   you detect a usab le header, slice it ou t ofth e  buf f er  andpass it up s tre am  ( pre fe r ab ly on  aworkerthread). K eep  d oing this an d  w hatever is  up stream shoul d b e able  t o r e act a cco rding ly. Ho p e that  helps.
S ou sually you hav e astru cture like this:B yt e Buffer reUsabl eBuffe r=  B y t eBu ffe r.allocate Di rect( 5 120);
S e le c t o r s e lector = Sele ctor.open() ; 
Se rverSo ck etC h annelchann el =..  // whereve r yo u get itfrom c hannel. r egister (selec tor , S elec t io nK ey. OP _ ACC E PT );E xec utor exe cu to r = E xecu t o r s .new Thr eadP oolEx ecutor();
whi le( sele c tor .isOp en())  {  i nt nu mKey =  sele ct or.select();
 f or ( Selection Key  k ey:  s elect o r.sele cte dKe ys()) { 
    if (ke y. i s A cc eptable()) {
        /// So rt ofi nc lu d ed for c om ple tene s s  butyoug et  the ide a
       Serve rS ocketC ha nne l s erver = (S erverS ocketCha nnel) k ey.channel();          Soc k et C h an n el c han nel = serve r.ac c ept( );
      ch annel .r e gi s ter(selector, Selec ti onKey. OP_RE AD | Selectio n.OP_WRITE , n ew Strin gBui l de r ());
    }   if (k ey.isReada b le()) {         //READ thed a ta
        r eUs abl e B uf fer.clear();      // Yo u h ave tokee p t rac k o fpreviousstate.
     //  NIOm akes nogu ara nt ees  of a n ything 
       St r ing Builder bu i l der=ke y.at tac hm ent() ;
       Soc ketChanne l s o cket Ch an nel = ( SocketChannel )k ey.channel () ;
      int rea dCount = socketChannel. r ead(reU sab leBuf fer) ;
        if (re adC o unt >0) {
       reUsa b l eB uff er .flip();
       byte [] subS tringBytes = new b y te[ readCount];
       re U sa b leB uf f er. r e ad(subStringByt es);
         // Assu m ing  A SCII (b ad assu mptio n  but si mplifiesthe examp le )
         buil der.appe nd(new St r ing(s u bs tring Byt es));
          Co m man d[] c ommand s= remo veCom ma nds(buil der);
             // D eal wi th yo urcommandsins ome  async ma nordefined by  yo u
         ex ecut o r. exe c ute(n ew T a sk(comman d s) );       }
    } 
     select or.s electedKeys().cle a r(); }....

   }

/ /
/ /  Par se  out the comma nds  a n d  returnth em, also re move tra ce s  of t hem in  the
/ / the b u i ld e r, suc h th atfor a str ing ," COMMAND ,CO M MAND,COM" 
/ / an a rray o f  2 s h o uld be returnedwith
 each_read I_would append the data_to the_builder,_and if__you detect a_usable header, slice_it out of the_buffer and pass_it_up stream (preferably on a worker thread). Keep doing this and whatever is upstream_should_be able_to_react_accordingly. Hope that helps.
So usually_you have a structure like_this:
ByteBuffer reUsableBuffer_= ByteBuffer.allocateDirect(5120);
Selector selector = Selector.open();
ServerSocketChannel channel =.. //_wherever_you get it_from 
channel.register(selector, SelectionKey.OP_ACCEPT);
Executor executor = Executors.newThreadPoolExecutor();
while(selector.isOpen()) { 
 int_numKey = selector.select();
 for (SelectionKey key:_selector.selectedKeys()) {
 ___if (key.isAcceptable()) {
 _     _     ///_Sort of included for completeness but you_get the idea
   _    _ _ServerSocketChannel server = (ServerSocketChannel)key.channel();
 _  _ _  _ SocketChannel channel = server.accept();
 _  _     _channel.register(selector,_SelectionKey.OP_READ | Selection.OP_WRITE,_new_StringBuilder());
_ _ } __ if_(key.isReadable())_{
     __   // READ the data
_   __   _reUsableBuffer.clear();
    _     //_You have_to keep_track of previous state.
       _  // NIO makes no_guarantees of anything
 _ __  __ StringBuilder_builder = key.attachment();
    _ _   SocketChannel socketChannel =_(SocketChannel)key.channel();
   __     int_readCount = socketChannel.read(reUsableBuffer);
   _    __if_(readCount > 0) {
 _     _  _  reUsableBuffer.flip();
    __     __byte[] subStringBytes = new byte[readCount];
 ___    _    reUsableBuffer.read(subStringBytes);
 _        _  //_Assuming ASCII (bad assumption but_simplifies_the_example)
         _ _ builder.append(new String(substringBytes));

_         _  Command[] commands = removeCommands(builder);
 _          _// Deal with your commands in some async_manor defined by you
   _   __    executor.execute(new Task(commands));
 ____  _  }
_  _ _  }
_ _  __ selector.selectedKeys().clear(); }....

    }   

//
// Parse out the commands and return them, also_remove traces of them in the
//_the builder, such that for_a_string, "COMMAND, COMMAND,_COM"
// an array of_2 should be returned with