NIOはTCPネットワーク通信を実現する
33875 ワード
NIOはTCPネットワーク通信を実現する
従来のソケットはIOモードをブロックして実現したソケット通信を採用しているが,ここでのブロックは実際にはプログラムとカーネルが相互作用するときのモードであり,NIOではNIOの特性を利用して非ブロック形式のソケット通信を実現できる
1.実装手順サービス側のポートリスニング を実現は、サービス側がクライアント接続を取得し、Selectorに登録する を実現する.メッセージ解析 を実装クライアントコードを実装し、 をテストする.
2.サービス側実現
2.1サービス側のポートリスニングの実現
2.2接続処理の実現は、取得したばかりのすべてのイベントのあるkeyを巡回し、イベントタイプがAcceptであるkeyを見つけるだけで、対応するチャネルをselectorに登録することができる である.
2.4メッセージ処理は、取得したばかりのすべてのイベントのあるkeyを巡回し、イベントタイプがReadableのkeyを見つけ、チャネル内のメッセージ を取得する必要がある.
2.5サービス・エンドの完全なコード
3.クライアント実装
従来のソケットはIOモードをブロックして実現したソケット通信を採用しているが,ここでのブロックは実際にはプログラムとカーネルが相互作用するときのモードであり,NIOではNIOの特性を利用して非ブロック形式のソケット通信を実現できる
1.実装手順
2.サービス側実現
2.1サービス側のポートリスニングの実現
public class MyServer {
private ServerSocketChannel serverSocketChannel;
private Selector selector;
/**
*
*/
public void start(Integer port) throws Exception{
serverSocketChannel = ServerSocketChannel.open();
selector = Selector.open();
//
serverSocketChannel.socket().bind(new InetSocketAddress(port));
//
serverSocketChannel.configureBlocking(false);
// Selector
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
startListener();
}
/**
*
*/
private void startListener() throws Exception {
while (true) {
// select
if (selector.select(1000) == 0) {
System.out.println("current not exists task");
continue;
}
// key
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
}
}
}
2.2接続処理の実現
private void startListener() throws Exception {
while (true) {
if (selector.select(1000) == 0) {
System.out.println("current not exists task");
continue;
}
// key
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
// key Accept key
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isAcceptable())
handleConnection();
iterator.remove();
}
}
}
/**
*
*/
private void handleConnection() throws Exception {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
}
2.4メッセージ処理
private void startListener() throws Exception {
while (true) {
if (selector.select(1000) == 0) {
System.out.println("current not exists task");
continue;
}
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isAcceptable())
handleConnection();
if (key.isReadable())
handleMsg(key);
iterator.remove();
}
}
}
private void handleMsg(SelectionKey key) throws Exception {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer attachment = (ByteBuffer) key.attachment();
channel.read(attachment);
System.out.println("current msg: " + new String(attachment.array()));
}
2.5サービス・エンドの完全なコード
public class MyServer {
private ServerSocketChannel serverSocketChannel;
private Selector selector;
public void start(Integer port) throws Exception{
serverSocketChannel = ServerSocketChannel.open();
selector = Selector.open();
serverSocketChannel.socket().bind(new InetSocketAddress(port));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
startListener();
}
private void startListener() throws Exception {
while (true) {
if (selector.select(1000) == 0) {
System.out.println("current not exists task");
continue;
}
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isAcceptable())
handleConnection();
if (key.isReadable())
handleMsg(key);
iterator.remove();
}
}
}
private void handleMsg(SelectionKey key) throws Exception {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer attachment = (ByteBuffer) key.attachment();
channel.read(attachment);
System.out.println("current msg: " + new String(attachment.array()));
}
private void handleConnection() throws Exception {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
}
public static void main(String[] args) throws Exception {
MyServer myServer = new MyServer();
myServer.start(8888);
}
}
3.クライアント実装
public class MyClient {
public static void main(String[] args) throws Exception {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
//
if (!socketChannel.connect(new InetSocketAddress("127.0.0.1", 8888))) {
while (!socketChannel.finishConnect()) {
System.out.println("connecting...");
}
}
//
String str = "hello netty";
ByteBuffer byteBuffer = ByteBuffer.wrap(str.getBytes());
socketChannel.write(byteBuffer);
System.in.read();
}
}