Java NIO: how to find out when a SocketChannel read () is full of non-blocking I / O

I am currently using a non-blocking SocketChannel (Java 1.6) to work as a client on a Redis server. Redis accepts clear-text commands directly through a socket terminated by CRLF and reacts as if a quick example:

SEND: 'PING \ r \ n'

RECV: '+ PONG \ r \ n'

Redis can also return huge responses (depending on what you request) with many data sections ending with \ r \ n as part of a single response.

I use the while (socket.read ()> 0) {// append bytes} loop standard to read bytes from the socket and reassemble them on the client side in response.

NOTE. I do not use a selector, only a few client SocketChannels connected to the server, awaiting service of send / receive commands.

What I'm confused about is the contract of the SocketChannel.read () method in non-blocking mode, in particular, how to find out when the server will be sent, and I have the whole message.

I have several ways to protect myself from returning too quickly and to allow the server to respond, but one thing I'm stuck for is this:

  • Is it possible when read () returns bytes, and then the subsequent call does not return the bytes, and on another subsequent call returns some bytes again?

, , , 1 , read() 0, , , , , sputter , ?

, read() 0 ( ), , , , java. io. * , "".

, , , read -1, , DB-, .

, ( , NIO) , Grizzly, MINA Netty - , , , .

.

:

, SocketChannel , , , -, .

, , , SocketChannel.read() , , ... - -. , ... , , SocketChannel.read() , ( , ).

, , .

+5
4

, read() 0 ( ), , , , java. io. * , "".

:

http://redis.io/topics/protocol

. , .

Redis . , :

  • "+"
  • "-"
  • ":"
  • "$"
  • "*"

, "+", "\ r\n" ....

...

, LRANGE, ( , LRANGE ). , , , .


, read() , , ? , , , 1 , read() 0, , , , , ?

, . , , "" . , "" .

. , , . , .


, SocketChannel , , , -, .

, . , . , BufferedReader , , , .

+3

Redis .

.read() 0 1 . . - , - Redis, .

, , - : " Redis , , , , ?"

Redis. , , , . Redis , Redis. , , . . Redis .

, Redis , . , , , , , . , , , .

+4

while (socket.read() > 0) {//append bytes} loop

NIO. :

  • -1, EOS, ,
  • , , select()
  • , , , ByteBuffer (get()/compact()), .
+2

, .,

SocketChannel

, SocketChannels ; , SocketChannel#configureBlocking(false)

,

; ; , ( , ); , , . read(ByteBuffer) == 0 (, , tcp ).

, ; , ? ?

, SocketChannel.read() , , , , .

β†’ , , SocketChannel#read(ByteBuffer), , > 0 (, ByteBuffer arg )

This is why you use the selector and because it can select the call "pick" 1Ks SocketChannels in one, which have bytes ready to read

Now there is nothing wrong with using SocketChannels in default lock mode; and given your description (a customer or two), there is probably no reason for it to be simpler; but if you want to use non-blocking channels, use the selector

+2
source

All Articles