简体   繁体   中英

Java nio read() return -1

it's not my first time trying to understand this issue but i hope it will be the last one:

some background:

i have a Java SocketChannel NIO server working in non-blocking mode.

this server has multiple clients which send and receive messages from it.

each client maintain its connection to the server with "keepalive" messages every once in a while. The main idea with the server is that the clients will remain connect "all the time" and receive messages from it in "push" mode.

now to my question:

in Java NIO read() function - when the read() return -1 - it means that its EOS.

in the question i've asked here i realized that it means that the socket has finished its current stream and doesn't need to be closed..

when searching in google a bit more about this i found out that it does mean that the connection is closed on the other side..

  1. what does the word "stream" exactly means? is it the current message being sent from the client? is it the ability of the client side connection to send anymore messages ?

  2. why would a SocketChannel be closed on the client side if the client never told him to be closed ?

  3. what is the difference between read() return -1 and connection reset by peer I/O error ?

this is how i read from SocketChannel :

private JSONObject readIncomingData(SocketChannel socketChannel)
        throws JSONException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException {
    JSONObject returnObject = null;
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    Charset charset = Charset.forName("UTF-8");
    String endOfMesesage = "\"}";
    String message = "";
    StringBuilder input = new StringBuilder();      
    boolean continueReading = true;
    while (continueReading && socketChannel.isOpen()) 
    {
        buffer.clear();         
        int bytesRead = socketChannel.read(buffer);             
        if (bytesRead == -1)
        {
            continueReading = false;                    
            continue;
        }
        buffer.flip();
        input.append(charset.decode(buffer));
        message = input.toString();
        if (message.contains(endOfMesesage))
            continueReading = false;
    }       
    if (input.length() > 0 && message.contains(endOfMesesage))
    {
        JSONObject messageJson = new JSONObject(input.toString());
        returnObject = new JSONObject(encrypter.decrypt(messageJson.getString("m")));
    }           
    return returnObject;
}

What does the word "stream" exactly means? is it the current message being sent from the client? is it the ability of the client side connection to send anymore messages ?

The stream means the data that is flowing between two locations, usually between the client and the server but effectively it's any kind of data flowing. Eg if you read a file from your hard disc you use a FileInputStream which represents data flowing from the file on disc to your program. It's a very generic concept. Think of it as a river where the water is the data. Plus it's a very cool kind of river which allows you to control how the water/data is flowing.

Why would a SocketChannel be closed on the client side if the client never told him to be closed ?

That can happen if the connection between client and server is reset or interrupted. Your program should never assume that connections just live and are never interrupted. Connections are interrupted for all kinds of reasons, may it be a flaky network component, someone pulling a plug that should better be left where it was or the wireless network is going down. Also the server might close the connection, eg if the server program goes down, has a bug or the connection runs into a timeout. Always remember that open connections are a limited resource so servers might decide to close them if they are idle for too long.

What is the difference between read() return -1 and connection reset by peer I/O error ?

When the read() returns -1 this simply means that there is currently no more data in the stream. A connection reset means, there was probably more data, but the connection no longer exists and therefore this data cannot be read anymore. Again taking the river anology: Think of the data as some quantity of water being sent from a village upstream (aka Serverville) to a village downstream (aka Clientville) using a riverbed that connects the two villages (the connection). Now someone at Serverville pulls the big lever and the water (the data) flows down from Serverville to Clientville. After Serverville has sent all the water it wanted to send, it closes the lever and the riverbed will be empty again (and actually destroyed as the connection got closed). This is where Clientville get's the -1. Now imagine some bulldozer interrupting the riverbed and some of the water never makes it to Clientville. This is the "connection reset" situation.

Hope this helps :)

what does the word "stream" exactly means? is it the current message being sent from the client?

It is a stream of bytes, not messages. You can use those bytes to form a message but the stream has no idea you are doing this, nor does it support messages in any way.

why would a SocketChannel be closed on the client side if the client never told him to be closed ?

It can only be closed with a -1 if the other end closed it.

what is the difference between read() return -1 and connection reset by peer I/O error ?

You can close or drop a connection other ways such as closing it from the same side, or a timeout in the connection egyou pulled out the network cable.

BTW: The way you have written the code is better suited to blocking NIO. For example, if you receive more than one whole message, anything after the first one is discarded. If you use blocking IO and keep everything you read you will not get corrupted or dropped messages.

  1. What does the word "stream" exactly means? is it the current message being sent from the client?

It basically means one side of the connection, which is full-duplex. TCP is a byte-stream protocol, providing two independent byte streams, one in each direction.

  1. Why would a SocketChannel be closed on the client side if the client never told him to be closed?

It wouldn't. The client did close the connection. That's what read() returning -1 means.

What is the difference between read() return -1 and connection reset by peer I/O error ?

read() returning -1 means the peer closed the connection properly. 'Connection reset by peer' indicates a protocol error of some kind, usually that you have written data to a connection that had already been closed by the peer.

Re your code, if read() returns -1 you must close the channel. There is no other sensible way to proceed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM