2

Java NIOの仕組みを理解しようとしています。特に、SocketChannel はどのように機能しますか。

私は以下のコードを書きました:

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. Googleサーバーに接続してみます。
  2. サーバーにリクエストを送信します。
  3. サーバーから回答を読み取ります。

ただし、メソッド socketChannel.read(buf) は常に 0 を返し、無限に実行されます。

どこで間違えた??

4

5 に答える 5

6

NIO SocektChannelデータが読み取り可能になるまでブロックしないためです。つまり、ノンブロッキング チャネルはreturn 0 on read() operation.

そのため、NIO を使用している間は、データが利用可能な場合にチャネルで読み取り通知を行うjava.nio.channels.Selectorを使用する必要があります。

一方、ブロッキング チャネルは、データが利用可能になるまで待機し、利用可能なデータ量を返します。つまり、ブロッキング チャネルは決してreturn 0 on read() operation.

NIO の詳細については、こちらをご覧ください。

于 2012-07-12T11:47:07.913 に答える
5

あなたは具体的に設定しました

socketChannel.configureBlocking(false);

ブロックしているデフォルトのままにすると、長さ 0 が返されることはありません。

于 2012-07-12T12:21:51.847 に答える
2

タイトルを読んでいる間、私は次のように言いました: b/c バッファに余裕がありません:

これまでの答えとは異なり、本当の原因は buf.clear().flip();、これが効果的にバッファをそのように設定することですposition=limit=0-したがって、データが読み取られません-に変更するbuf.clear()と、準備が整いました。

質問を投稿する前に、NIO を楽しんだり、デバッガーを使用したりしてください。

于 2012-07-12T13:32:54.327 に答える
0

本当に非ブロッキング I/O を使用したい場合は、セレクターを使用するか、Java 7 の nio2 (AsynchronousSocketChannel など) を使用してください。nio2 の使用は比較的簡単です。

于 2012-07-12T14:22:06.270 に答える
-1

技術的な説明は、完全な HTTP リクエストを Google Web サーバーに送信していないため、完全なリクエストを受信するまで応答を送信しないことです。

これは、読み取りに使用できるデータがないことを意味する 0 バイトを読み取っている理由を説明しています。

于 2015-08-08T19:20:33.563 に答える