Thanks a lot for you answer, I will study about filters and try your solution too.
Thanks too much really. -----Mensagem original----- De: Jon V. [mailto:[email protected]] Enviada em: segunda-feira, 2 de setembro de 2013 23:54 Para: [email protected] Assunto: Re: Send/Receive IoBuffer This is better: I am not going to use the correct API but you can get the idea. Create a Filter called CompoundBufferFilter filter_received( ByteBuffer source, IoSession session, Filter next ) { ByteBuffer buffering = session.getAttribute( SOME_PROPERTY_BUFFER_NAME ); if( buffering == null ) { buffering = ByteBuffer.allocate( some size ); } buffering.put( source ); buffering.flip(); next.received( buffering, session ); } This will compound buffer incoming data. logic_received( ByteBuffer source, IoSession session ) { while( source.hasRemaining() ) { source.mark(); if( source.remaining < 4 ) { source.reset(); return; } int size = source.getInt(); if( source.remaining < size ) { source.reset(); return; } String data = new String( buffering.array, buffering.offset, size, "ISO-8859-1"); } source.compact(); } Now you can simply "return" if you don't have enough data. On Mon, Sep 2, 2013 at 10:42 PM, Jon V. <[email protected]> wrote: > > > > On Mon, Sep 2, 2013 at 10:21 PM, Luciano Coelho <[email protected]>wrote: > >> Yeah Jon, you're right about flush, the wrong thing is really the >> IoBuffer. >> I put the: session.getConfig().setReadBufferSize(16*1024), on >> connector as you told me. >> >> I changed now for what you answered me, like this: >> >> if(size > 0){ >> while (buffer.hasRemaining()){ >> byte[] payload = new byte[size]; >> buffer.get(payload); >> data = new String( payload, "ISO-8859-1"); >> } >> } >> > > Ok - Mina does not allow for compound rx_buffers. This means you are > going to have to manually buffer the message yourself. > > > received( ByteBuffer source, IoSession session ) { while( > source.hasRemaining() ) { ByteBuffer buffering = > session.getAttribute( SOME_PROPERTY_BUFFER_NAME ); > > if( buffering != null ) > { > // must be a new data > int size = // read size somehow > buffering = ByteBuffer.allocate( size ); > > buffering.put(source); > > if( buffering.hasRemaining() ) > { > session.setAttribute( SOME_PROPERTY_BUFFER_NAME, buffering ); return; > } > else > { > // message is complete > session.clearAttribute( SOME_PROPERTY_BUFFER_NAME ); String data = new > String( buffering.array, buffering.offset, buffering.limit, > "ISO-8859-1"); > } > } > else > { > buffering.put(source); > if( !buffering.hasRemaining() ) > { > // message is complete > session.clearAttribute( SOME_PROPERTY_BUFFER_NAME ); String data = > new String( buffering.array, buffering.offset, buffering.limit, > "ISO-8859-1"); } else { return; } } } } > > In MINA you have to read everything out of that ByteBuffer or it will > be lost forever. This means you could get stuck only having 2 bytes > in the buffer and not enough to read the size value. So you may have > to setup a secondary buffer to store partial size values if that scenario does occur. > > >> >> I'm receiving from de server 2685 bytes and I set the buffer to >> 64*1024, and I'm still having the error: D/WEB(26934): >> java.nio.BufferUnderflowException. >> >> I saw that setting tcpnodelay = false becomes better, I got make 3 >> requests without error, but after the error happens again, and I have >> to restart the session again. >> Do I have to finish something in the IoBuffer after receive the data? >> Note that I'm not opening another session, I open one time and stay >> changing data all the time. The rest is functioning very well, one by >> one minute I send something and the server answer quickly, the only >> problem now is this big request that one time goes another time not. >> >> Thank's again. >> >> LUCIANO >> >> -----Mensagem original----- >> De: Jon V. [mailto:[email protected]] Enviada em: segunda-feira, 2 >> de setembro de 2013 19:26 >> Para: [email protected] >> Assunto: Re: Send/Receive IoBuffer >> >> On Mon, Sep 2, 2013 at 5:37 PM, Luciano Coelho >> <[email protected]>wrote: >> >> > Hello everybody. >> > >> > >> > >> > I'm learning how to use Mina and my questions are: >> > >> > >> > >> > I solved my problem of having a answer from my server without >> > closing the session like this: >> > >> > >> > >> > System.out.flush(); >> > >> >> >> This really gives me an indication of your Java knowledge. >> System.out is your access to stdout in Java. It is what you use to >> print things to the console. It has nothing to do with your application. >> >> Maybe posting on StackOverflow would be a good idea for general java help? >> >> >> > >> > >> > >> > Is that ok? >> > >> > >> > >> > I'm receiving the answer in Android via GPRS like this: >> > >> > >> > >> > First I set this on sessionCreated >> > >> > session.getConfig().setReadBufferSize(16*1024); >> > >> > >> > >> You should set this in Mina config. It is not good to change on the >> fly like this. >> >> Read the Quick Start Guide: >> http://mina.apache.org/mina-project/quick-start-guide.html >> >> >> > >> > @Override public void messageReceived(IoSession session, Object >> > message) throws Exception { >> > >> > IoBuffer buffer >> > = (IoBuffer) message; >> > >> > int service >> > = (Integer) session.getAttribute("SERVICE"); >> > >> > Listener listener >> > = (Listener) session.getAttribute("LISTENER"); >> > >> > String data >> > = ""; >> > >> > int size >> > = buffer.getInt(); >> > >> > while (buffer.hasRemaining()){ >> > >> > data += (char) buffer.get(); >> > >> >> Using the += is the worst possible way to build a String. >> >> Since you are reading a String. Are you sure that the String is >> encoded using 8 bits? >> >> byte[] payload = new byte[size]; >> buffer.get(payload); >> >> String data = new String( payload, "UTF-8"); >> >> >> >> > >> > } >> > >> > if(size == data.trim().length()){ >> > >> >> Why are you trying to trim the string? Are you expecting whitespaces? >> >> >> > >> > if(listener != null) >> > listener.requisitionFinished(data, service); >> > >> > } else { >> > >> > if(listener != null) >> > listener.requisitionFinished("", service); >> > >> > } >> > >> > Log.d("WEB", "SERVICE: " + service + " SIZE: " + >> > size + >> " >> > DATA: " + data); >> > >> > } >> > >> > >> > >> > Sometimes I receive the data in parts, when the message arriving is >> > too long and it causes an error, even if the buffersize is bigger >> > than the data I'm receiving. >> > >> > >> > >> > Thank's a lot. >> > >> > >> > >> > Luciano Coelho >> > >> > >> >> >
