user471011
user471011

Reputation: 7384

Java NIO. SocketChannel.read method all time return 0. Why?

I try understand how works java NIO. In particular, how works SocketChannel.

I wrote code below:

import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;

public class Test {

    public static void main(String[] args) throws IOException {

        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.configureBlocking(false);
        socketChannel.connect(new InetSocketAddress("google.com", 80));

        while (!socketChannel.finishConnect()) {
            // wait, or do something else...
        }

        String newData = "Some String...";

        ByteBuffer buf = ByteBuffer.allocate(48);
        buf.clear();
        buf.put(newData.getBytes());

        buf.flip();

        while (buf.hasRemaining()) {
            System.out.println(socketChannel.write(buf));
        }

        buf.clear().flip();

        int bytesRead;

        while ((bytesRead = socketChannel.read(buf)) != -1) {

            System.out.println(bytesRead);

        }

    }

}
  1. I try connect to google server.
  2. Send request to the server;
  3. Read answer from the server.

but, method socketChannel.read(buf) all time return 0 and performs infinitely.

Where I made mistake??

Upvotes: 2

Views: 12541

Answers (5)

Ramesh PVK
Ramesh PVK

Reputation: 15456

Because NIO SocektChannel will not block until the data is available for read. i.e, Non Blocking Channel can return 0 on read() operation.

That is why while using NIO you should be using java.nio.channels.Selector which gives you read notification on channel if the data is available.

On the otherhand, blocking channel will wait till the data is available and return how much data is available. i.e, Blocking channel will never return 0 on read() operation.

You can read more about NIO here:

Upvotes: 6

user1187372
user1187372

Reputation: 193

The technical explanation is that you didn't send a complete HTTP request to the google webserver, therefore it won't send you a reply until it receives a complete request.

This explains why you are reading 0 bytes which means that no data is available for reading.

Upvotes: -1

Alexei Kaigorodov
Alexei Kaigorodov

Reputation: 13535

If you really want to use non-blocking I/O, then either use selector, or use nio2 (AsynchronousSocketChannel et al.) from Java 7. Using selector is tricky, better find ready working examples. Using nio2 is relatively easy.

Upvotes: 0

bestsss
bestsss

Reputation: 12066

While reading the title I was about the say: b/c there is no room in the buffer:

Unlike the answers so far the real culprit is buf.clear().flip(); this effectively sets the buffer like that position=limit=0 - hence no data read - change to buf.clear() and you are good to go.

Have fun w/ the NIO and use debugger before posting a question.

Upvotes: 2

Peter Lawrey
Peter Lawrey

Reputation: 533820

You have specifically configured

socketChannel.configureBlocking(false);

If you left the default which is blocking then you would never get a length of 0 returned.

Upvotes: 5

Related Questions