ブロッキングモード / ノンブロッキングモード
ブロッキングモード
* 読み込みや書き込みを完了するまで待つ(=制御をブロックする)
API
* java.net.ServerSocket
ノンブロッキングモード
* 今できる処理(read/write)して、すぐに制御が戻る * ノンブロッキングモードの詳細は以下の関連記事を参照のことhttp://blogs.yahoo.co.jp/dk521123/35120798.html
API
* java.nio.channels.ServerSocketChannel(ブロッキングモード / ノンブロッキングモードどちらも使える) * java.nio.channels.AsynchronousServerSocketChannel
サンプル
サーバ側
ChannelSampleServer.java
* 実行しておくimport java.net.InetSocketAddress; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; public class ChannelSampleServer { public static final int PORT = 12345; public static void main(String[] args) { ChannelSampleServer server = new ChannelSampleServer(); server.start(); } public void start() { try (ServerSocketChannel serverChannel = ServerSocketChannel.open();) { serverChannel.socket().bind(new InetSocketAddress(PORT)); System.out.println("起動しました port = " + serverChannel.socket().getLocalPort()); while (true) { SocketChannel channel = serverChannel.accept(); System.out.println(channel.socket().getRemoteSocketAddress() + " : 接続されました"); ChannelServerThread channelServerThread = new ChannelServerThread(channel); channelServerThread.start(); } } catch (Exception ex) { ex.printStackTrace(); } } }
ChannelServerThread.java
import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; public class ChannelServerThread extends Thread { private static final int BUFFER_SIZE = 1000; private SocketChannel channel = null; public ChannelServerThread(SocketChannel channel) { this.channel = channel; } public void run() { ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); String remoteAddress = this.channel.socket().getRemoteSocketAddress() .toString(); try { if (this.channel.read(buffer) < 0) { return; } buffer.flip(); Charset charset = Charset.forName("UTF-8"); String input = charset.decode(buffer).toString(); System.out.print(remoteAddress + " : " + input); buffer.flip(); this.channel.write(buffer); } catch (Exception ex) { ex.printStackTrace(); return; } finally { System.out.println(remoteAddress + " : 切断しました "); if (this.channel != null && this.channel.isOpen()) { try { this.channel.close(); } catch (IOException e) { } } } } }
クライアント側
ChannelSampleClient.java
* サーバ側を起動したら、こちらを起動するimport java.io.BufferedReader; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; public class ChannelSampleClient { public static final int PORT = 12345; public static final int BUFFER_SIZE = 1000; public static void main(String[] args) { try (SocketChannel channel = SocketChannel.open(new InetSocketAddress("localhost", PORT));) { BufferedReader in = new BufferedReader(new InputStreamReader( System.in)); System.out.print("送信:"); String line = in.readLine(); ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); Charset charset = Charset.forName("UTF-8"); channel.write(charset.encode(CharBuffer.wrap(line + "\n"))); while (channel.isConnected()) { buffer.clear(); if (channel.read(buffer) < 0) { return; } buffer.flip(); System.out.print("受信:" + charset.decode(buffer).toString()); } } catch (Exception ex) { ex.printStackTrace(); } } }
出力結果
■ クライアント側の表示
「hellow」って入力すると...送信:hellow 受信:hellow
■ サーバ側の表示
起動しました port = 12345 /127.0.0.1:63073 : 接続されました /127.0.0.1:63073 : hellow /127.0.0.1:63073 : 切断しました
参考文献
* 非常にシンプルで分かりやすいhttp://www.akirakoyasu.net/2013/06/09/how-to-implement-tcp-server-in-java-1-5/
http://www.javainthebox.net/laboratory/JDK1.4/NewIO/SocketChannel/SocketChannel.html
http://www.techscore.com/tech/Java/JavaSE/NIO/5/
http://otn.oracle.co.jp/technology/global/jp/sdn/java/private/techtips/2004/tt0914.html
http://www.akirakoyasu.net/2013/06/09/how-to-implement-tcp-server-in-java-1-5/
http://itpro.nikkeibp.co.jp/article/COLUMN/20060515/237871/
http://www.torutk.com/projects/swe/wiki/Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0_TCP%E9%80%9A%E4%BF%A1_%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E4%BD%BF%E7%94%A8%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8
http://itpro.nikkeibp.co.jp/article/COLUMN/20060508/237029/
http://javaabc.sakura.ne.jp/nonblocking.shtml
https://blogs.oracle.com/yosshi/entry/grizzly%E3%81%AE%E6%A6%82%E8%A6%81_2_java_new_i
http://asistobe851.web.fc2.com/JAVA/non-blocking-io-by-java.html