Java-nio-socket-channel

提供:Dev Guides
移動先:案内検索

Java NIO-ソケットチャネル

Java NIOソケットチャネルは、セレクタを使用して多重化できる選択可能なタイプのチャネルであり、ソケットを接続するストリーム指向のデータフローに使用されます。ソケットチャネルは、静的* open()メソッドを呼び出すことで作成できます。ソケットチャネルは、openメソッドを呼び出すことで作成されますが、まだ接続されていません。ソケットチャネルを接続するには、 connect()メソッドを呼び出します。ここで言及する1つのポイントは、チャネルが接続されておらず、I/O操作が試行されると、このチャネルによってNotYetConnectedExceptionがスローされます。したがって、IO操作を実行する前にチャネルが接続されていることを確認する必要があります。チャネルが接続されると、閉じられるまで接続されたままになります。ソケットチャネルの状態は、 *isConnected メソッドを呼び出して決定します。

ソケットチャネルの接続は、その* finishConnect()*メソッドを呼び出すことで終了できます。接続操作が進行中かどうかは、isConnectionPendingメソッドを呼び出すことで決定できます。デフォルトでは、ソケットチャネルは非ブロッキング接続をサポートします。シャットダウン。Channelクラスで指定された非同期のクローズ操作に似ています。

ソケットチャネルは、複数の同時スレッドで安全に使用できます。 同時読み取りと書き込みをサポートしていますが、常に最大で1つのスレッドが読み取りを行い、最大1つのスレッドが書き込みを行うことができます。 connectメソッドとfinishConnectメソッドは相互に同期しており、これらのメソッドのいずれかの呼び出しが進行中に読み取りまたは書き込み操作を開始しようとすると、その呼び出しが完了するまでブロックされます。

ソケットチャネルの重要なメソッド

  • * bind(SocketAddress local)*-このメソッドは、このメソッドのパラメーターとして提供されるローカルアドレスにソケットチャネルをバインドするために使用されます。
  • * connect(SocketAddress remote)*-このメソッドは、ソケットをリモートアドレスに接続するために使用されます。
  • * finishConnect()*-このメソッドは、ソケットチャネルの接続プロセスを終了するために使用されます。
  • * getRemoteAddress()*-このメソッドは、チャネルのソケットが接続されているリモートロケーションのアドレスを返します。
  • * isConnected()*-すでに述べたように、このメソッドはソケットチャネルの接続状態、つまり接続されているかどうかを返します。
  • * open()and open((SocketAddress remote)*-Openメソッドは指定されたアドレスのないソケットチャネルを開き、パラメータ化されたopenメソッドは指定されたリモートアドレスのチャネルを開いて接続します。この便利なメソッドは、 open()メソッド。結果のソケットチャネルでconnectメソッドを呼び出し、リモートに渡し、そのチャネルを返します。
  • * read(ByteBuffer dst)*-このメソッドは、ソケットチャネルを介して指定されたバッファからデータを読み取るために使用されます。
  • * isConnectionPending()*-このメソッドは、このチャネルで接続操作が進行中かどうかを示します。

次の例は、Java NIO SocketChannelからデータを送信する方法を示しています。

C:/Test/temp.txt

Hello World!

クライアント:SocketChannelClient.java

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.EnumSet;

public class SocketChannelClient {
   public static void main(String[] args) throws IOException {
      ServerSocketChannel serverSocket = null;
      SocketChannel client = null;
      serverSocket = ServerSocketChannel.open();
      serverSocket.socket().bind(new InetSocketAddress(9000));
      client = serverSocket.accept();
      System.out.println("Connection Set:  " + client.getRemoteAddress());
      Path path = Paths.get("C:/Test/temp1.txt");
      FileChannel fileChannel = FileChannel.open(path,
         EnumSet.of(StandardOpenOption.CREATE,
            StandardOpenOption.TRUNCATE_EXISTING,
            StandardOpenOption.WRITE)
         );
      ByteBuffer buffer = ByteBuffer.allocate(1024);
      while(client.read(buffer) > 0) {
         buffer.flip();
         fileChannel.write(buffer);
         buffer.clear();
      }
      fileChannel.close();
      System.out.println("File Received");
      client.close();
   }
}

出力

クライアントを実行しても、サーバーが起動するまで何も出力されません。

サーバー:SocketChannelServer.java

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;
import java.nio.file.Paths;

public class SocketChannelServer {
   public static void main(String[] args) throws IOException {
      SocketChannel server = SocketChannel.open();
      SocketAddress socketAddr = new InetSocketAddress("localhost", 9000);
      server.connect(socketAddr);

      Path path = Paths.get("C:/Test/temp.txt");
      FileChannel fileChannel = FileChannel.open(path);
      ByteBuffer buffer = ByteBuffer.allocate(1024);
      while(fileChannel.read(buffer) > 0) {
         buffer.flip();
         server.write(buffer);
         buffer.clear();
      }
      fileChannel.close();
      System.out.println("File Sent");
      server.close();
   }
}

出力

サーバーを実行すると、次が出力されます。

Connection Set: /127.0.0.1:49558
File Received