【Java】SocketChannel / ServerSocketChannel ~ノンブロッキングモード編~

サンプル

サーバ側

 * 実行しておく

NioServer.java

import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.Selector;
import java.nio.channels.SelectionKey;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.Set;
import java.util.Iterator;
import java.net.InetSocketAddress;

public class NioServer {
   private static final int PORT = 18080;

   public static void main(String[] args) throws IOException {
      Selector selector = Selector.open();
      System.out.println("Selector open : " + selector.isOpen());
      ServerSocketChannel serverSocket = ServerSocketChannel.open();
      InetSocketAddress hostAddress = new InetSocketAddress("localhost", PORT);
      serverSocket.bind(hostAddress);
      serverSocket.configureBlocking(false);
      SelectionKey selectionKey = serverSocket.register(selector, serverSocket.validOps(), null);

      while (true) {
         System.out.println("Waiting...");
         int keyNo = selector.select();
         System.out.println("Key No : " + keyNo);
         Set<SelectionKey> selectedKeys = selector.selectedKeys();
         Iterator<SelectionKey> iterator = selectedKeys.iterator();
         while (iterator.hasNext()) {
            SelectionKey nextSelectionKey = iterator.next();
            if (nextSelectionKey.isAcceptable()) {
               // Accept the new client connection
               SocketChannel client = serverSocket.accept();
               client.configureBlocking(false);
               // Add the new connection to the selector
               client.register(selector, SelectionKey.OP_READ);
               System.out.println("Accepted new connection from client: "
                     + client);
            } else if (nextSelectionKey.isReadable()) {
               // Read the data from client
               SocketChannel client = (SocketChannel) nextSelectionKey.channel();
               ByteBuffer buffer = ByteBuffer.allocate(256);
               client.read(buffer);
               String output = new String(buffer.array()).trim();
               System.out.println("Message from client: " + output);
               if (output.equals("Fin...")) {
                  client.close();
                  System.out.println("Client messages are complete; close.");
               }
            }
            iterator.remove();
         }
      }
   }
}

クライアント側

 * サーバ側を実行させたら実行する

NioClient.java

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class NioClient {
   private static final int PORT = 18080;

   public static void main(String[] args) throws IOException,
         InterruptedException {
      InetSocketAddress hostAddress = new InetSocketAddress("localhost", PORT);
      SocketChannel client = SocketChannel.open(hostAddress);
      System.out.println("Client sending messages to server...");

      // Send messages to server
      String[] sendingMessages = new String[] { "First data. Did you get it?", "Second data, can you get it?", "Fin..." };

      for (String sendingMessage : sendingMessages) {
         byte[] messages = sendingMessage.getBytes();
         ByteBuffer buffer = ByteBuffer.wrap(messages);
         client.write(buffer);
         System.out.println(sendingMessage);
         buffer.clear();
         Thread.sleep(3000);
      }
      client.close();
   }
}

実行結果

クライアント側

Client sending messages to server...
First data. Did you get it?
Second data, can you get it?
Fin...

サーバ側

Selector open : true
Waiting...
Key No : 1
Accepted new connection from client: java.nio.channels.SocketChannel[connected local=/127.0.0.1:18080 remote=/127.0.0.1:52595]
Waiting...
Key No : 1
Message from client: First data. Did you get it?
Waiting...
Key No : 1
Message from client: Second data, can you get it?
Waiting...
Key No : 1
Message from client: Fin...
Client messages are complete; close.
Waiting...


関連記事

Socket 通信を行う ~Server側/Client側の実装例~

http://blogs.yahoo.co.jp/dk521123/33075148.html

Java で、SSL通信を行うには

http://blogs.yahoo.co.jp/dk521123/33122920.html

SocketChannel / ServerSocketChannel ~ブロッキングモード編~

http://blogs.yahoo.co.jp/dk521123/35067257.html

ノンブロッキングチャネル の SSL接続

http://blogs.yahoo.co.jp/dk521123/35077762.html