sockets - Java NIO with InputStream.available() -


good day.

i'm using nio multiplexing , don't want allocate additional buffers in app till sure have enough bytes in socket read entire application packet. each application packet contains 4 bytes of packet length (header) , following bytes of packet body. want read 4 bytes of packet length if available , following bytes of packet body if available. so, code can that:

private final bytebuffer read_buffer = bytebuffer.wrap(new byte[read_buffer_size]); ... iterator<selectionkey> selectedkeys = selector.selectedkeys().iterator();  while (selectedkeys.hasnext()) {     selectionkey key = selectedkeys.next();     selectedkeys.remove();      connection con = (connection) key.attachment();      switch (key.readyops())     {         case selectionkey.op_accept:             acceptconnection(key);             break;         case selectionkey.op_read:             readpacket(key, con);    //**     } } ... private final void readpacket(final selectionkey key, final connection con) {        read_buffer.clear();     int result = -2;      try     {         result = con.read(read_buffer);     }     catch (ioexception e) {}      //* packet processing goes here } 

in * can obtain:

  1. less 4 bytes read header;
  2. 4 bytes header not enough bytes packet body
  3. enough bytes read n packets (header + body), part of (n+1) packet

in either of 3 cases have store readed data in additional bytebuffer, read_buffer used next connection in **.

what want do:

public class connection {     private final bytechannel bytechannel;     private final inputstream in;     private int lastpacketsize = -1;      connection(final socket socket)     {         bytechannel = socket.getchannel();         in = socket.getinputstream();     }      int read(final bytebuffer buf) throws ioexception     {         return bytechannel.read(buf);     }      int available()     {         return in.available();     }      void setlastpacketsize(int size)     {         lastpacketsize = size;     }      int getlastpacketsize()     {         return lastpacketsize;     } }  private final intbuffer header_buffer = intbuffer.wrap(new int[1]); private final void readpacket(final selectionkey key, final connection con) {     int packetsize = con.getlastpacketsize();     if (packetsize < 0)     {         if (con.available() < 4) return;          int result = -2;         header_buffer.clear();         try         {             result = con.read(header_buffer);         }         catch (ioexception e) {}          if (result != 4)         {             closeconnection(key);             return;         }          packetsize = header_buffer.get();         con.setlastpacketsize(packetsize);     }      if (con.available() < packetsize) return;      result = -2;      read_buffer.clear();     read_buffer.limit(packetsize);     try     {         result = con.read(read_buffer);     }     catch (ioexception e) {}      if (result != packetsize)     {         closeconnection(key);         return;     }     con.setlastpacketsize(-1);      //packet processing goes here } 

i have found under hood socket's inputstream uses ioctl(fd, fionread, pbytes) on linux. can rely on con.available() in scenario or can fail? if can fail reasons , how improve code overcome these reasons?

if you're using non-blocking mode can't use inputstream @ all. can't have ever run code.

there's not point in you're trying do. read every time op_read fires until have enough data process.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -