java - Unexpected behavior of tcp server: why adding delay increases ability to service clients? -


good day everybody!

my question nio based server , situation following: server reads messages 100 clients (100 client threads) send 100 messages each. so, total number of messages 100x100 = 10000. have incoming messages counter in server increases after reading message client. when read message server reads approximately 9200 messages. when add dummy loop simulationg service delay server surprisingly services 10000 messages!

my expectations - ok, server manages read 10000 messages short delay. so, without delay server can read more messages (service more clients). see, wrong. without delay things getting worse. here described architechture. modification in current logic dividing accepting clients , reading messages 2 different threads: 1 selector accepts clients in 1 thread, second selector waits messages connected clients in other thread.

client code

public class tcpclient implements runnable{  private string name; private static tcpclient[] clients; private static thread[] threads; private int counter = 0;  public tcpclient(string name) {   this.name = name;   this.counter = 0; }  public static void main(string[] args) throws exception {    clients = new tcpclient[100];    threads = new thread[100];    for(int i=0;i<100;i++)     {        clients[i] = new tcpclient("thread # "+integer.tostring(i));        threads[i] = new thread(clients[i]);        threads[i].start();         // thread.sleep(500);    }    for(int i=0;i<100;i++)     {        threads[i].join();    }    for(int i=0;i<100;i++){        system.out.println("counter = "+clients[i].counter);    }  }  @override public void run() {    socket socket = null;    outputstream out = null;     try    {         socket = new socket();         socket.connect(new inetsocketaddress("192.168.3.109",2345), 0);          out =  socket.getoutputstream();          byte[] bytes;         while(counter < 100)         {             counter++;             bytes = (name+ ", message # "+integer.tostring(counter)+system.lineseparator()).getbytes();            // system.out.println(counter);             out.write(bytes);              out.flush();             thread.sleep(200);         }    }    catch(exception ex)    {             system.out.println(name+" "+integer.tostring(counter));             ex.printstacktrace(new printstream(system.out));             system.out.println();    }         {          if(socket!=null && out!=null)         {             try             {                 socket.close();                 out.close();             }             catch(exception ex)             {                 system.out.println("client close error");             }         }     } }  } 

server code (message reading part)

@override public void run()  {     isrunning = true;     int acc = 0;     boolean error = false;     while (isrunning) {       try        {                selector.select();                set keys =  selector.selectedkeys();              iterator = keys.iterator();               while(it.hasnext())              {                  selectionkey key = (selectionkey)it.next();                     if (key.isreadable())                  {                         //readmessage(key);                        //key.cancel();                        // bytebuffer bbb =  bytebuffer.allocate(2048);                       // key.cancel();                        curtime = system.currenttimemillis();                        socketchannel sc = (socketchannel) key.channel();                        // system.out.println("before reading");                         bb.clear();                        int x =  sc.read(bb);                          if(x==-1)                        {                            key.cancel();                            //system.out.println("cancelling key");                            continue;                        }                         counter++;                       // bb.flip();                        //system.out.print(decoder.decode(bb).tostring());                      //  thread.sleep(20);                        long sum=0;                        for(int dummy=0;dummy<250000;dummy++)                        {                            sum += dummy;                          //  sum %= 1005;                        }                        long delta  = system.currenttimemillis() - curtime;                        servicetime += delta;                         if(counter>9000)                        {                            system.out.println("recieved messages count = "+counter);                            system.out.println("one message  service time = "+delta+" milliseconds");                            system.out.println("total service time = "+servicetime+" milliseconds");                            system.out.println("sum = "+sum); //11 249 925 000                        }                       // selector.wakeup();                       //key.interestops(selectionkey.op_read);                     }               }               keys.clear();            }        catch (exception ex)        {                error = true;             system.out.println("error in recieving messages "+ex.getmessage());           ex.printstacktrace(new printstream(system.out));          // logger.println("error in recieving messages "+ex.getmessage());          // logger.flush();       }             {             //if(error) // !!!!!!!!!!! not stop server edit later             //stopserver();       }     } } 

probably useful information - delay between each 2 messages on client side 200 milliseconds. when dummy loop makes 200000-220000 iterations server works perfectly. btw, 200000 iterations approximately 200 ms - beacause number of clients 100, delay in 1 select() 100*200000 = 2 million iterations - 200 ms modern pc. if dummy loop makes less 200000 iterations server reads ~9200 messages. reason of such strange behavior?

there many problems here difficult know start.

  1. when read() returns -1 must close channel. cancelling key not sufficent: have leaked socket.

  2. if read() returns positive integer, read count, ignoring. assuming got entire message.

  3. if ioexception doing i/o on channel must close channel.

probably aren't receiving entire message unless put sleeps in. or else when put sleeps in more 1 message @ time, process faster.

adding sleeps fixes bugs, doesn't have magical properties of own.


Comments

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

delphi - Dynamic file type icon -