JavaNIO-ソケットチャネル

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 NIOSocketChannelからデータを送信する方法を示しています。

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